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                        cx,
  440                    )
  441                    .await?;
  442
  443                    let mut initialization_options = Self::initialization_options_for_adapter(
  444                        adapter.adapter.clone(),
  445                        &delegate,
  446                    )
  447                    .await?;
  448
  449                    match (&mut initialization_options, override_options) {
  450                        (Some(initialization_options), Some(override_options)) => {
  451                            merge_json_value_into(override_options, initialization_options);
  452                        }
  453                        (None, override_options) => initialization_options = override_options,
  454                        _ => {}
  455                    }
  456
  457                    let initialization_params = cx.update(|cx| {
  458                        let mut params =
  459                            language_server.default_initialize_params(pull_diagnostics, cx);
  460                        params.initialization_options = initialization_options;
  461                        adapter.adapter.prepare_initialize_params(params, cx)
  462                    })??;
  463
  464                    Self::setup_lsp_messages(
  465                        lsp_store.clone(),
  466                        &language_server,
  467                        delegate.clone(),
  468                        adapter.clone(),
  469                    );
  470
  471                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  472                        settings: workspace_config,
  473                    };
  474                    let language_server = cx
  475                        .update(|cx| {
  476                            language_server.initialize(
  477                                initialization_params,
  478                                Arc::new(did_change_configuration_params.clone()),
  479                                cx,
  480                            )
  481                        })?
  482                        .await
  483                        .inspect_err(|_| {
  484                            if let Some(lsp_store) = lsp_store.upgrade() {
  485                                lsp_store
  486                                    .update(cx, |lsp_store, cx| {
  487                                        lsp_store.cleanup_lsp_data(server_id);
  488                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  489                                    })
  490                                    .ok();
  491                            }
  492                        })?;
  493
  494                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  495                        did_change_configuration_params,
  496                    )?;
  497
  498                    anyhow::Ok(language_server)
  499                }
  500                .await;
  501
  502                match result {
  503                    Ok(server) => {
  504                        lsp_store
  505                            .update(cx, |lsp_store, cx| {
  506                                lsp_store.insert_newly_running_language_server(
  507                                    adapter,
  508                                    server.clone(),
  509                                    server_id,
  510                                    key,
  511                                    pending_workspace_folders,
  512                                    cx,
  513                                );
  514                            })
  515                            .ok();
  516                        stderr_capture.lock().take();
  517                        Some(server)
  518                    }
  519
  520                    Err(err) => {
  521                        let log = stderr_capture.lock().take().unwrap_or_default();
  522                        delegate.update_status(
  523                            adapter.name(),
  524                            BinaryStatus::Failed {
  525                                error: if log.is_empty() {
  526                                    format!("{err:#}")
  527                                } else {
  528                                    format!("{err:#}\n-- stderr --\n{log}")
  529                                },
  530                            },
  531                        );
  532                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  533                        if !log.is_empty() {
  534                            log::error!("server stderr: {log}");
  535                        }
  536                        None
  537                    }
  538                }
  539            })
  540        };
  541        let state = LanguageServerState::Starting {
  542            startup,
  543            pending_workspace_folders,
  544        };
  545
  546        self.languages
  547            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  548
  549        self.language_servers.insert(server_id, state);
  550        self.language_server_ids
  551            .entry(key)
  552            .or_insert(UnifiedLanguageServer {
  553                id: server_id,
  554                project_roots: Default::default(),
  555            });
  556        server_id
  557    }
  558
  559    fn get_language_server_binary(
  560        &self,
  561        adapter: Arc<CachedLspAdapter>,
  562        settings: Arc<LspSettings>,
  563        toolchain: Option<Toolchain>,
  564        delegate: Arc<dyn LspAdapterDelegate>,
  565        allow_binary_download: bool,
  566        cx: &mut App,
  567    ) -> Task<Result<LanguageServerBinary>> {
  568        if let Some(settings) = &settings.binary
  569            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  570        {
  571            let settings = settings.clone();
  572
  573            return cx.background_spawn(async move {
  574                let mut env = delegate.shell_env().await;
  575                env.extend(settings.env.unwrap_or_default());
  576
  577                Ok(LanguageServerBinary {
  578                    path: delegate.resolve_executable_path(path),
  579                    env: Some(env),
  580                    arguments: settings
  581                        .arguments
  582                        .unwrap_or_default()
  583                        .iter()
  584                        .map(Into::into)
  585                        .collect(),
  586                })
  587            });
  588        }
  589        let lsp_binary_options = LanguageServerBinaryOptions {
  590            allow_path_lookup: !settings
  591                .binary
  592                .as_ref()
  593                .and_then(|b| b.ignore_system_version)
  594                .unwrap_or_default(),
  595            allow_binary_download,
  596            pre_release: settings
  597                .fetch
  598                .as_ref()
  599                .and_then(|f| f.pre_release)
  600                .unwrap_or(false),
  601        };
  602
  603        cx.spawn(async move |cx| {
  604            let (existing_binary, maybe_download_binary) = adapter
  605                .clone()
  606                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  607                .await
  608                .await;
  609
  610            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  611
  612            let mut binary = match (existing_binary, maybe_download_binary) {
  613                (binary, None) => binary?,
  614                (Err(_), Some(downloader)) => downloader.await?,
  615                (Ok(existing_binary), Some(downloader)) => {
  616                    let mut download_timeout = cx
  617                        .background_executor()
  618                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  619                        .fuse();
  620                    let mut downloader = downloader.fuse();
  621                    futures::select! {
  622                        _ = download_timeout => {
  623                            // Return existing binary and kick the existing work to the background.
  624                            cx.spawn(async move |_| downloader.await).detach();
  625                            Ok(existing_binary)
  626                        },
  627                        downloaded_or_existing_binary = downloader => {
  628                            // If download fails, this results in the existing binary.
  629                            downloaded_or_existing_binary
  630                        }
  631                    }?
  632                }
  633            };
  634            let mut shell_env = delegate.shell_env().await;
  635
  636            shell_env.extend(binary.env.unwrap_or_default());
  637
  638            if let Some(settings) = settings.binary.as_ref() {
  639                if let Some(arguments) = &settings.arguments {
  640                    binary.arguments = arguments.iter().map(Into::into).collect();
  641                }
  642                if let Some(env) = &settings.env {
  643                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  644                }
  645            }
  646
  647            binary.env = Some(shell_env);
  648            Ok(binary)
  649        })
  650    }
  651
  652    fn setup_lsp_messages(
  653        lsp_store: WeakEntity<LspStore>,
  654        language_server: &LanguageServer,
  655        delegate: Arc<dyn LspAdapterDelegate>,
  656        adapter: Arc<CachedLspAdapter>,
  657    ) {
  658        let name = language_server.name();
  659        let server_id = language_server.server_id();
  660        language_server
  661            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  662                let adapter = adapter.clone();
  663                let this = lsp_store.clone();
  664                move |mut params, cx| {
  665                    let adapter = adapter.clone();
  666                    if let Some(this) = this.upgrade() {
  667                        this.update(cx, |this, cx| {
  668                            {
  669                                let buffer = params
  670                                    .uri
  671                                    .to_file_path()
  672                                    .map(|file_path| this.get_buffer(&file_path, cx))
  673                                    .ok()
  674                                    .flatten();
  675                                adapter.process_diagnostics(&mut params, server_id, buffer);
  676                            }
  677
  678                            this.merge_lsp_diagnostics(
  679                                DiagnosticSourceKind::Pushed,
  680                                vec![DocumentDiagnosticsUpdate {
  681                                    server_id,
  682                                    diagnostics: params,
  683                                    result_id: None,
  684                                    disk_based_sources: Cow::Borrowed(
  685                                        &adapter.disk_based_diagnostic_sources,
  686                                    ),
  687                                }],
  688                                |_, diagnostic, cx| match diagnostic.source_kind {
  689                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  690                                        adapter.retain_old_diagnostic(diagnostic, cx)
  691                                    }
  692                                    DiagnosticSourceKind::Pulled => true,
  693                                },
  694                                cx,
  695                            )
  696                            .log_err();
  697                        })
  698                        .ok();
  699                    }
  700                }
  701            })
  702            .detach();
  703        language_server
  704            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  705                let adapter = adapter.adapter.clone();
  706                let delegate = delegate.clone();
  707                let this = lsp_store.clone();
  708                move |params, cx| {
  709                    let adapter = adapter.clone();
  710                    let delegate = delegate.clone();
  711                    let this = this.clone();
  712                    let mut cx = cx.clone();
  713                    async move {
  714                        let toolchain_for_id = this
  715                            .update(&mut cx, |this, _| {
  716                                this.as_local()?.language_server_ids.iter().find_map(
  717                                    |(seed, value)| {
  718                                        (value.id == server_id).then(|| seed.toolchain.clone())
  719                                    },
  720                                )
  721                            })?
  722                            .context("Expected the LSP store to be in a local mode")?;
  723                        let workspace_config = Self::workspace_configuration_for_adapter(
  724                            adapter.clone(),
  725                            &delegate,
  726                            toolchain_for_id,
  727                            &mut cx,
  728                        )
  729                        .await?;
  730
  731                        Ok(params
  732                            .items
  733                            .into_iter()
  734                            .map(|item| {
  735                                if let Some(section) = &item.section {
  736                                    workspace_config
  737                                        .get(section)
  738                                        .cloned()
  739                                        .unwrap_or(serde_json::Value::Null)
  740                                } else {
  741                                    workspace_config.clone()
  742                                }
  743                            })
  744                            .collect())
  745                    }
  746                }
  747            })
  748            .detach();
  749
  750        language_server
  751            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  752                let this = lsp_store.clone();
  753                move |_, cx| {
  754                    let this = this.clone();
  755                    let cx = cx.clone();
  756                    async move {
  757                        let Some(server) =
  758                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  759                        else {
  760                            return Ok(None);
  761                        };
  762                        let root = server.workspace_folders();
  763                        Ok(Some(
  764                            root.into_iter()
  765                                .map(|uri| WorkspaceFolder {
  766                                    uri,
  767                                    name: Default::default(),
  768                                })
  769                                .collect(),
  770                        ))
  771                    }
  772                }
  773            })
  774            .detach();
  775        // Even though we don't have handling for these requests, respond to them to
  776        // avoid stalling any language server like `gopls` which waits for a response
  777        // to these requests when initializing.
  778        language_server
  779            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  780                let this = lsp_store.clone();
  781                move |params, cx| {
  782                    let this = this.clone();
  783                    let mut cx = cx.clone();
  784                    async move {
  785                        this.update(&mut cx, |this, _| {
  786                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  787                            {
  788                                status
  789                                    .progress_tokens
  790                                    .insert(ProgressToken::from_lsp(params.token));
  791                            }
  792                        })?;
  793
  794                        Ok(())
  795                    }
  796                }
  797            })
  798            .detach();
  799
  800        language_server
  801            .on_request::<lsp::request::RegisterCapability, _, _>({
  802                let lsp_store = lsp_store.clone();
  803                move |params, cx| {
  804                    let lsp_store = lsp_store.clone();
  805                    let mut cx = cx.clone();
  806                    async move {
  807                        lsp_store
  808                            .update(&mut cx, |lsp_store, cx| {
  809                                if lsp_store.as_local().is_some() {
  810                                    match lsp_store
  811                                        .register_server_capabilities(server_id, params, cx)
  812                                    {
  813                                        Ok(()) => {}
  814                                        Err(e) => {
  815                                            log::error!(
  816                                                "Failed to register server capabilities: {e:#}"
  817                                            );
  818                                        }
  819                                    };
  820                                }
  821                            })
  822                            .ok();
  823                        Ok(())
  824                    }
  825                }
  826            })
  827            .detach();
  828
  829        language_server
  830            .on_request::<lsp::request::UnregisterCapability, _, _>({
  831                let lsp_store = lsp_store.clone();
  832                move |params, cx| {
  833                    let lsp_store = lsp_store.clone();
  834                    let mut cx = cx.clone();
  835                    async move {
  836                        lsp_store
  837                            .update(&mut cx, |lsp_store, cx| {
  838                                if lsp_store.as_local().is_some() {
  839                                    match lsp_store
  840                                        .unregister_server_capabilities(server_id, params, cx)
  841                                    {
  842                                        Ok(()) => {}
  843                                        Err(e) => {
  844                                            log::error!(
  845                                                "Failed to unregister server capabilities: {e:#}"
  846                                            );
  847                                        }
  848                                    }
  849                                }
  850                            })
  851                            .ok();
  852                        Ok(())
  853                    }
  854                }
  855            })
  856            .detach();
  857
  858        language_server
  859            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  860                let this = lsp_store.clone();
  861                move |params, cx| {
  862                    let mut cx = cx.clone();
  863                    let this = this.clone();
  864                    async move {
  865                        LocalLspStore::on_lsp_workspace_edit(
  866                            this.clone(),
  867                            params,
  868                            server_id,
  869                            &mut cx,
  870                        )
  871                        .await
  872                    }
  873                }
  874            })
  875            .detach();
  876
  877        language_server
  878            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  879                let lsp_store = lsp_store.clone();
  880                let request_id = Arc::new(AtomicUsize::new(0));
  881                move |(), cx| {
  882                    let lsp_store = lsp_store.clone();
  883                    let request_id = request_id.clone();
  884                    let mut cx = cx.clone();
  885                    async move {
  886                        lsp_store
  887                            .update(&mut cx, |lsp_store, cx| {
  888                                let request_id =
  889                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  890                                cx.emit(LspStoreEvent::RefreshInlayHints {
  891                                    server_id,
  892                                    request_id,
  893                                });
  894                                lsp_store
  895                                    .downstream_client
  896                                    .as_ref()
  897                                    .map(|(client, project_id)| {
  898                                        client.send(proto::RefreshInlayHints {
  899                                            project_id: *project_id,
  900                                            server_id: server_id.to_proto(),
  901                                            request_id: request_id.map(|id| id as u64),
  902                                        })
  903                                    })
  904                            })?
  905                            .transpose()?;
  906                        Ok(())
  907                    }
  908                }
  909            })
  910            .detach();
  911
  912        language_server
  913            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  914                let this = lsp_store.clone();
  915                move |(), cx| {
  916                    let this = this.clone();
  917                    let mut cx = cx.clone();
  918                    async move {
  919                        this.update(&mut cx, |this, cx| {
  920                            cx.emit(LspStoreEvent::RefreshCodeLens);
  921                            this.downstream_client.as_ref().map(|(client, project_id)| {
  922                                client.send(proto::RefreshCodeLens {
  923                                    project_id: *project_id,
  924                                })
  925                            })
  926                        })?
  927                        .transpose()?;
  928                        Ok(())
  929                    }
  930                }
  931            })
  932            .detach();
  933
  934        language_server
  935            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  936                let this = lsp_store.clone();
  937                move |(), cx| {
  938                    let this = this.clone();
  939                    let mut cx = cx.clone();
  940                    async move {
  941                        this.update(&mut cx, |lsp_store, _| {
  942                            lsp_store.pull_workspace_diagnostics(server_id);
  943                            lsp_store
  944                                .downstream_client
  945                                .as_ref()
  946                                .map(|(client, project_id)| {
  947                                    client.send(proto::PullWorkspaceDiagnostics {
  948                                        project_id: *project_id,
  949                                        server_id: server_id.to_proto(),
  950                                    })
  951                                })
  952                        })?
  953                        .transpose()?;
  954                        Ok(())
  955                    }
  956                }
  957            })
  958            .detach();
  959
  960        language_server
  961            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  962                let this = lsp_store.clone();
  963                let name = name.to_string();
  964                move |params, cx| {
  965                    let this = this.clone();
  966                    let name = name.to_string();
  967                    let mut cx = cx.clone();
  968                    async move {
  969                        let actions = params.actions.unwrap_or_default();
  970                        let (tx, rx) = smol::channel::bounded(1);
  971                        let request = LanguageServerPromptRequest {
  972                            level: match params.typ {
  973                                lsp::MessageType::ERROR => PromptLevel::Critical,
  974                                lsp::MessageType::WARNING => PromptLevel::Warning,
  975                                _ => PromptLevel::Info,
  976                            },
  977                            message: params.message,
  978                            actions,
  979                            response_channel: tx,
  980                            lsp_name: name.clone(),
  981                        };
  982
  983                        let did_update = this
  984                            .update(&mut cx, |_, cx| {
  985                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  986                            })
  987                            .is_ok();
  988                        if did_update {
  989                            let response = rx.recv().await.ok();
  990                            Ok(response)
  991                        } else {
  992                            Ok(None)
  993                        }
  994                    }
  995                }
  996            })
  997            .detach();
  998        language_server
  999            .on_notification::<lsp::notification::ShowMessage, _>({
 1000                let this = lsp_store.clone();
 1001                let name = name.to_string();
 1002                move |params, cx| {
 1003                    let this = this.clone();
 1004                    let name = name.to_string();
 1005                    let mut cx = cx.clone();
 1006
 1007                    let (tx, _) = smol::channel::bounded(1);
 1008                    let request = LanguageServerPromptRequest {
 1009                        level: match params.typ {
 1010                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1011                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1012                            _ => PromptLevel::Info,
 1013                        },
 1014                        message: params.message,
 1015                        actions: vec![],
 1016                        response_channel: tx,
 1017                        lsp_name: name,
 1018                    };
 1019
 1020                    let _ = this.update(&mut cx, |_, cx| {
 1021                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1022                    });
 1023                }
 1024            })
 1025            .detach();
 1026
 1027        let disk_based_diagnostics_progress_token =
 1028            adapter.disk_based_diagnostics_progress_token.clone();
 1029
 1030        language_server
 1031            .on_notification::<lsp::notification::Progress, _>({
 1032                let this = lsp_store.clone();
 1033                move |params, cx| {
 1034                    if let Some(this) = this.upgrade() {
 1035                        this.update(cx, |this, cx| {
 1036                            this.on_lsp_progress(
 1037                                params,
 1038                                server_id,
 1039                                disk_based_diagnostics_progress_token.clone(),
 1040                                cx,
 1041                            );
 1042                        })
 1043                        .ok();
 1044                    }
 1045                }
 1046            })
 1047            .detach();
 1048
 1049        language_server
 1050            .on_notification::<lsp::notification::LogMessage, _>({
 1051                let this = lsp_store.clone();
 1052                move |params, cx| {
 1053                    if let Some(this) = this.upgrade() {
 1054                        this.update(cx, |_, cx| {
 1055                            cx.emit(LspStoreEvent::LanguageServerLog(
 1056                                server_id,
 1057                                LanguageServerLogType::Log(params.typ),
 1058                                params.message,
 1059                            ));
 1060                        })
 1061                        .ok();
 1062                    }
 1063                }
 1064            })
 1065            .detach();
 1066
 1067        language_server
 1068            .on_notification::<lsp::notification::LogTrace, _>({
 1069                let this = lsp_store.clone();
 1070                move |params, cx| {
 1071                    let mut cx = cx.clone();
 1072                    if let Some(this) = this.upgrade() {
 1073                        this.update(&mut cx, |_, cx| {
 1074                            cx.emit(LspStoreEvent::LanguageServerLog(
 1075                                server_id,
 1076                                LanguageServerLogType::Trace {
 1077                                    verbose_info: params.verbose,
 1078                                },
 1079                                params.message,
 1080                            ));
 1081                        })
 1082                        .ok();
 1083                    }
 1084                }
 1085            })
 1086            .detach();
 1087
 1088        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1089        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1090        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1091        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1092    }
 1093
 1094    fn shutdown_language_servers_on_quit(
 1095        &mut self,
 1096        _: &mut Context<LspStore>,
 1097    ) -> impl Future<Output = ()> + use<> {
 1098        let shutdown_futures = self
 1099            .language_servers
 1100            .drain()
 1101            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1102            .collect::<Vec<_>>();
 1103
 1104        async move {
 1105            join_all(shutdown_futures).await;
 1106        }
 1107    }
 1108
 1109    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1110        match server_state {
 1111            LanguageServerState::Running { server, .. } => {
 1112                if let Some(shutdown) = server.shutdown() {
 1113                    shutdown.await;
 1114                }
 1115            }
 1116            LanguageServerState::Starting { startup, .. } => {
 1117                if let Some(server) = startup.await
 1118                    && let Some(shutdown) = server.shutdown()
 1119                {
 1120                    shutdown.await;
 1121                }
 1122            }
 1123        }
 1124        Ok(())
 1125    }
 1126
 1127    fn language_servers_for_worktree(
 1128        &self,
 1129        worktree_id: WorktreeId,
 1130    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1131        self.language_server_ids
 1132            .iter()
 1133            .filter_map(move |(seed, state)| {
 1134                if seed.worktree_id != worktree_id {
 1135                    return None;
 1136                }
 1137
 1138                if let Some(LanguageServerState::Running { server, .. }) =
 1139                    self.language_servers.get(&state.id)
 1140                {
 1141                    Some(server)
 1142                } else {
 1143                    None
 1144                }
 1145            })
 1146    }
 1147
 1148    fn language_server_ids_for_project_path(
 1149        &self,
 1150        project_path: ProjectPath,
 1151        language: &Language,
 1152        cx: &mut App,
 1153    ) -> Vec<LanguageServerId> {
 1154        let Some(worktree) = self
 1155            .worktree_store
 1156            .read(cx)
 1157            .worktree_for_id(project_path.worktree_id, cx)
 1158        else {
 1159            return Vec::new();
 1160        };
 1161        let delegate: Arc<dyn ManifestDelegate> =
 1162            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1163
 1164        self.lsp_tree
 1165            .get(
 1166                project_path,
 1167                language.name(),
 1168                language.manifest(),
 1169                &delegate,
 1170                cx,
 1171            )
 1172            .collect::<Vec<_>>()
 1173    }
 1174
 1175    fn language_server_ids_for_buffer(
 1176        &self,
 1177        buffer: &Buffer,
 1178        cx: &mut App,
 1179    ) -> Vec<LanguageServerId> {
 1180        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1181            let worktree_id = file.worktree_id(cx);
 1182
 1183            let path: Arc<RelPath> = file
 1184                .path()
 1185                .parent()
 1186                .map(Arc::from)
 1187                .unwrap_or_else(|| file.path().clone());
 1188            let worktree_path = ProjectPath { worktree_id, path };
 1189            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1190        } else {
 1191            Vec::new()
 1192        }
 1193    }
 1194
 1195    fn language_servers_for_buffer<'a>(
 1196        &'a self,
 1197        buffer: &'a Buffer,
 1198        cx: &'a mut App,
 1199    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1200        self.language_server_ids_for_buffer(buffer, cx)
 1201            .into_iter()
 1202            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1203                LanguageServerState::Running {
 1204                    adapter, server, ..
 1205                } => Some((adapter, server)),
 1206                _ => None,
 1207            })
 1208    }
 1209
 1210    async fn execute_code_action_kind_locally(
 1211        lsp_store: WeakEntity<LspStore>,
 1212        mut buffers: Vec<Entity<Buffer>>,
 1213        kind: CodeActionKind,
 1214        push_to_history: bool,
 1215        cx: &mut AsyncApp,
 1216    ) -> anyhow::Result<ProjectTransaction> {
 1217        // Do not allow multiple concurrent code actions requests for the
 1218        // same buffer.
 1219        lsp_store.update(cx, |this, cx| {
 1220            let this = this.as_local_mut().unwrap();
 1221            buffers.retain(|buffer| {
 1222                this.buffers_being_formatted
 1223                    .insert(buffer.read(cx).remote_id())
 1224            });
 1225        })?;
 1226        let _cleanup = defer({
 1227            let this = lsp_store.clone();
 1228            let mut cx = cx.clone();
 1229            let buffers = &buffers;
 1230            move || {
 1231                this.update(&mut cx, |this, cx| {
 1232                    let this = this.as_local_mut().unwrap();
 1233                    for buffer in buffers {
 1234                        this.buffers_being_formatted
 1235                            .remove(&buffer.read(cx).remote_id());
 1236                    }
 1237                })
 1238                .ok();
 1239            }
 1240        });
 1241        let mut project_transaction = ProjectTransaction::default();
 1242
 1243        for buffer in &buffers {
 1244            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1245                buffer.update(cx, |buffer, cx| {
 1246                    lsp_store
 1247                        .as_local()
 1248                        .unwrap()
 1249                        .language_servers_for_buffer(buffer, cx)
 1250                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1251                        .collect::<Vec<_>>()
 1252                })
 1253            })?;
 1254            for (_, language_server) in adapters_and_servers.iter() {
 1255                let actions = Self::get_server_code_actions_from_action_kinds(
 1256                    &lsp_store,
 1257                    language_server.server_id(),
 1258                    vec![kind.clone()],
 1259                    buffer,
 1260                    cx,
 1261                )
 1262                .await?;
 1263                Self::execute_code_actions_on_server(
 1264                    &lsp_store,
 1265                    language_server,
 1266                    actions,
 1267                    push_to_history,
 1268                    &mut project_transaction,
 1269                    cx,
 1270                )
 1271                .await?;
 1272            }
 1273        }
 1274        Ok(project_transaction)
 1275    }
 1276
 1277    async fn format_locally(
 1278        lsp_store: WeakEntity<LspStore>,
 1279        mut buffers: Vec<FormattableBuffer>,
 1280        push_to_history: bool,
 1281        trigger: FormatTrigger,
 1282        logger: zlog::Logger,
 1283        cx: &mut AsyncApp,
 1284    ) -> anyhow::Result<ProjectTransaction> {
 1285        // Do not allow multiple concurrent formatting requests for the
 1286        // same buffer.
 1287        lsp_store.update(cx, |this, cx| {
 1288            let this = this.as_local_mut().unwrap();
 1289            buffers.retain(|buffer| {
 1290                this.buffers_being_formatted
 1291                    .insert(buffer.handle.read(cx).remote_id())
 1292            });
 1293        })?;
 1294
 1295        let _cleanup = defer({
 1296            let this = lsp_store.clone();
 1297            let mut cx = cx.clone();
 1298            let buffers = &buffers;
 1299            move || {
 1300                this.update(&mut cx, |this, cx| {
 1301                    let this = this.as_local_mut().unwrap();
 1302                    for buffer in buffers {
 1303                        this.buffers_being_formatted
 1304                            .remove(&buffer.handle.read(cx).remote_id());
 1305                    }
 1306                })
 1307                .ok();
 1308            }
 1309        });
 1310
 1311        let mut project_transaction = ProjectTransaction::default();
 1312
 1313        for buffer in &buffers {
 1314            zlog::debug!(
 1315                logger =>
 1316                "formatting buffer '{:?}'",
 1317                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1318            );
 1319            // Create an empty transaction to hold all of the formatting edits.
 1320            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1321                // ensure no transactions created while formatting are
 1322                // grouped with the previous transaction in the history
 1323                // based on the transaction group interval
 1324                buffer.finalize_last_transaction();
 1325                buffer
 1326                    .start_transaction()
 1327                    .context("transaction already open")?;
 1328                buffer.end_transaction(cx);
 1329                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1330                buffer.finalize_last_transaction();
 1331                anyhow::Ok(transaction_id)
 1332            })??;
 1333
 1334            let result = Self::format_buffer_locally(
 1335                lsp_store.clone(),
 1336                buffer,
 1337                formatting_transaction_id,
 1338                trigger,
 1339                logger,
 1340                cx,
 1341            )
 1342            .await;
 1343
 1344            buffer.handle.update(cx, |buffer, cx| {
 1345                let Some(formatting_transaction) =
 1346                    buffer.get_transaction(formatting_transaction_id).cloned()
 1347                else {
 1348                    zlog::warn!(logger => "no formatting transaction");
 1349                    return;
 1350                };
 1351                if formatting_transaction.edit_ids.is_empty() {
 1352                    zlog::debug!(logger => "no changes made while formatting");
 1353                    buffer.forget_transaction(formatting_transaction_id);
 1354                    return;
 1355                }
 1356                if !push_to_history {
 1357                    zlog::trace!(logger => "forgetting format transaction");
 1358                    buffer.forget_transaction(formatting_transaction.id);
 1359                }
 1360                project_transaction
 1361                    .0
 1362                    .insert(cx.entity(), formatting_transaction);
 1363            })?;
 1364
 1365            result?;
 1366        }
 1367
 1368        Ok(project_transaction)
 1369    }
 1370
 1371    async fn format_buffer_locally(
 1372        lsp_store: WeakEntity<LspStore>,
 1373        buffer: &FormattableBuffer,
 1374        formatting_transaction_id: clock::Lamport,
 1375        trigger: FormatTrigger,
 1376        logger: zlog::Logger,
 1377        cx: &mut AsyncApp,
 1378    ) -> Result<()> {
 1379        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1380            buffer.handle.update(cx, |buffer, cx| {
 1381                let adapters_and_servers = lsp_store
 1382                    .as_local()
 1383                    .unwrap()
 1384                    .language_servers_for_buffer(buffer, cx)
 1385                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1386                    .collect::<Vec<_>>();
 1387                let settings =
 1388                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1389                        .into_owned();
 1390                (adapters_and_servers, settings)
 1391            })
 1392        })?;
 1393
 1394        /// Apply edits to the buffer that will become part of the formatting transaction.
 1395        /// Fails if the buffer has been edited since the start of that transaction.
 1396        fn extend_formatting_transaction(
 1397            buffer: &FormattableBuffer,
 1398            formatting_transaction_id: text::TransactionId,
 1399            cx: &mut AsyncApp,
 1400            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1401        ) -> anyhow::Result<()> {
 1402            buffer.handle.update(cx, |buffer, cx| {
 1403                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1404                if last_transaction_id != Some(formatting_transaction_id) {
 1405                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1406                }
 1407                buffer.start_transaction();
 1408                operation(buffer, cx);
 1409                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1410                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1411                }
 1412                Ok(())
 1413            })?
 1414        }
 1415
 1416        // handle whitespace formatting
 1417        if settings.remove_trailing_whitespace_on_save {
 1418            zlog::trace!(logger => "removing trailing whitespace");
 1419            let diff = buffer
 1420                .handle
 1421                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1422                .await;
 1423            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1424                buffer.apply_diff(diff, cx);
 1425            })?;
 1426        }
 1427
 1428        if settings.ensure_final_newline_on_save {
 1429            zlog::trace!(logger => "ensuring final newline");
 1430            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1431                buffer.ensure_final_newline(cx);
 1432            })?;
 1433        }
 1434
 1435        // Formatter for `code_actions_on_format` that runs before
 1436        // the rest of the formatters
 1437        let mut code_actions_on_format_formatters = None;
 1438        let should_run_code_actions_on_format = !matches!(
 1439            (trigger, &settings.format_on_save),
 1440            (FormatTrigger::Save, &FormatOnSave::Off)
 1441        );
 1442        if should_run_code_actions_on_format {
 1443            let have_code_actions_to_run_on_format = settings
 1444                .code_actions_on_format
 1445                .values()
 1446                .any(|enabled| *enabled);
 1447            if have_code_actions_to_run_on_format {
 1448                zlog::trace!(logger => "going to run code actions on format");
 1449                code_actions_on_format_formatters = Some(
 1450                    settings
 1451                        .code_actions_on_format
 1452                        .iter()
 1453                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1454                        .cloned()
 1455                        .map(Formatter::CodeAction)
 1456                        .collect::<Vec<_>>(),
 1457                );
 1458            }
 1459        }
 1460
 1461        let formatters = match (trigger, &settings.format_on_save) {
 1462            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1463            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1464                settings.formatter.as_ref()
 1465            }
 1466        };
 1467
 1468        let formatters = code_actions_on_format_formatters
 1469            .iter()
 1470            .flatten()
 1471            .chain(formatters);
 1472
 1473        for formatter in formatters {
 1474            let formatter = if formatter == &Formatter::Auto {
 1475                if settings.prettier.allowed {
 1476                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1477                    &Formatter::Prettier
 1478                } else {
 1479                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1480                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1481                }
 1482            } else {
 1483                formatter
 1484            };
 1485            match formatter {
 1486                Formatter::Auto => unreachable!("Auto resolved above"),
 1487                Formatter::Prettier => {
 1488                    let logger = zlog::scoped!(logger => "prettier");
 1489                    zlog::trace!(logger => "formatting");
 1490                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1491
 1492                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1493                        lsp_store.prettier_store().unwrap().downgrade()
 1494                    })?;
 1495                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1496                        .await
 1497                        .transpose()?;
 1498                    let Some(diff) = diff else {
 1499                        zlog::trace!(logger => "No changes");
 1500                        continue;
 1501                    };
 1502
 1503                    extend_formatting_transaction(
 1504                        buffer,
 1505                        formatting_transaction_id,
 1506                        cx,
 1507                        |buffer, cx| {
 1508                            buffer.apply_diff(diff, cx);
 1509                        },
 1510                    )?;
 1511                }
 1512                Formatter::External { command, arguments } => {
 1513                    let logger = zlog::scoped!(logger => "command");
 1514                    zlog::trace!(logger => "formatting");
 1515                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1516
 1517                    let diff = Self::format_via_external_command(
 1518                        buffer,
 1519                        command.as_ref(),
 1520                        arguments.as_deref(),
 1521                        cx,
 1522                    )
 1523                    .await
 1524                    .with_context(|| {
 1525                        format!("Failed to format buffer via external command: {}", command)
 1526                    })?;
 1527                    let Some(diff) = diff else {
 1528                        zlog::trace!(logger => "No changes");
 1529                        continue;
 1530                    };
 1531
 1532                    extend_formatting_transaction(
 1533                        buffer,
 1534                        formatting_transaction_id,
 1535                        cx,
 1536                        |buffer, cx| {
 1537                            buffer.apply_diff(diff, cx);
 1538                        },
 1539                    )?;
 1540                }
 1541                Formatter::LanguageServer(specifier) => {
 1542                    let logger = zlog::scoped!(logger => "language-server");
 1543                    zlog::trace!(logger => "formatting");
 1544                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1545
 1546                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1547                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1548                        continue;
 1549                    };
 1550
 1551                    let language_server = match specifier {
 1552                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1553                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1554                                if adapter.name.0.as_ref() == name {
 1555                                    Some(server.clone())
 1556                                } else {
 1557                                    None
 1558                                }
 1559                            })
 1560                        }
 1561                        settings::LanguageServerFormatterSpecifier::Current => {
 1562                            adapters_and_servers.first().map(|e| e.1.clone())
 1563                        }
 1564                    };
 1565
 1566                    let Some(language_server) = language_server else {
 1567                        log::debug!(
 1568                            "No language server found to format buffer '{:?}'. Skipping",
 1569                            buffer_path_abs.as_path().to_string_lossy()
 1570                        );
 1571                        continue;
 1572                    };
 1573
 1574                    zlog::trace!(
 1575                        logger =>
 1576                        "Formatting buffer '{:?}' using language server '{:?}'",
 1577                        buffer_path_abs.as_path().to_string_lossy(),
 1578                        language_server.name()
 1579                    );
 1580
 1581                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1582                        zlog::trace!(logger => "formatting ranges");
 1583                        Self::format_ranges_via_lsp(
 1584                            &lsp_store,
 1585                            &buffer.handle,
 1586                            ranges,
 1587                            buffer_path_abs,
 1588                            &language_server,
 1589                            &settings,
 1590                            cx,
 1591                        )
 1592                        .await
 1593                        .context("Failed to format ranges via language server")?
 1594                    } else {
 1595                        zlog::trace!(logger => "formatting full");
 1596                        Self::format_via_lsp(
 1597                            &lsp_store,
 1598                            &buffer.handle,
 1599                            buffer_path_abs,
 1600                            &language_server,
 1601                            &settings,
 1602                            cx,
 1603                        )
 1604                        .await
 1605                        .context("failed to format via language server")?
 1606                    };
 1607
 1608                    if edits.is_empty() {
 1609                        zlog::trace!(logger => "No changes");
 1610                        continue;
 1611                    }
 1612                    extend_formatting_transaction(
 1613                        buffer,
 1614                        formatting_transaction_id,
 1615                        cx,
 1616                        |buffer, cx| {
 1617                            buffer.edit(edits, None, cx);
 1618                        },
 1619                    )?;
 1620                }
 1621                Formatter::CodeAction(code_action_name) => {
 1622                    let logger = zlog::scoped!(logger => "code-actions");
 1623                    zlog::trace!(logger => "formatting");
 1624                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1625
 1626                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1627                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1628                        continue;
 1629                    };
 1630
 1631                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1632                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1633
 1634                    let mut actions_and_servers = Vec::new();
 1635
 1636                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1637                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1638                            &lsp_store,
 1639                            language_server.server_id(),
 1640                            vec![code_action_kind.clone()],
 1641                            &buffer.handle,
 1642                            cx,
 1643                        )
 1644                        .await
 1645                        .with_context(|| {
 1646                            format!(
 1647                                "Failed to resolve code action {:?} with language server {}",
 1648                                code_action_kind,
 1649                                language_server.name()
 1650                            )
 1651                        });
 1652                        let Ok(actions) = actions_result else {
 1653                            // note: it may be better to set result to the error and break formatters here
 1654                            // but for now we try to execute the actions that we can resolve and skip the rest
 1655                            zlog::error!(
 1656                                logger =>
 1657                                "Failed to resolve code action {:?} with language server {}",
 1658                                code_action_kind,
 1659                                language_server.name()
 1660                            );
 1661                            continue;
 1662                        };
 1663                        for action in actions {
 1664                            actions_and_servers.push((action, index));
 1665                        }
 1666                    }
 1667
 1668                    if actions_and_servers.is_empty() {
 1669                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1670                        continue;
 1671                    }
 1672
 1673                    'actions: for (mut action, server_index) in actions_and_servers {
 1674                        let server = &adapters_and_servers[server_index].1;
 1675
 1676                        let describe_code_action = |action: &CodeAction| {
 1677                            format!(
 1678                                "code action '{}' with title \"{}\" on server {}",
 1679                                action
 1680                                    .lsp_action
 1681                                    .action_kind()
 1682                                    .unwrap_or("unknown".into())
 1683                                    .as_str(),
 1684                                action.lsp_action.title(),
 1685                                server.name(),
 1686                            )
 1687                        };
 1688
 1689                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1690
 1691                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1692                            zlog::error!(
 1693                                logger =>
 1694                                "Failed to resolve {}. Error: {}",
 1695                                describe_code_action(&action),
 1696                                err
 1697                            );
 1698                            continue;
 1699                        }
 1700
 1701                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1702                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1703                            // but filters out and logs warnings for code actions that require unreasonably
 1704                            // difficult handling on our part, such as:
 1705                            // - applying edits that call commands
 1706                            //   which can result in arbitrary workspace edits being sent from the server that
 1707                            //   have no way of being tied back to the command that initiated them (i.e. we
 1708                            //   can't know which edits are part of the format request, or if the server is done sending
 1709                            //   actions in response to the command)
 1710                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1711                            //   as we then would need to handle such changes correctly in the local history as well
 1712                            //   as the remote history through the ProjectTransaction
 1713                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1714                            // Supporting these actions is not impossible, but not supported as of yet.
 1715                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1716                                zlog::trace!(
 1717                                    logger =>
 1718                                    "No changes for code action. Skipping {}",
 1719                                    describe_code_action(&action),
 1720                                );
 1721                                continue;
 1722                            }
 1723
 1724                            let mut operations = Vec::new();
 1725                            if let Some(document_changes) = edit.document_changes {
 1726                                match document_changes {
 1727                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1728                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1729                                    ),
 1730                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1731                                }
 1732                            } else if let Some(changes) = edit.changes {
 1733                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1734                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1735                                        text_document:
 1736                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1737                                                uri,
 1738                                                version: None,
 1739                                            },
 1740                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1741                                    })
 1742                                }));
 1743                            }
 1744
 1745                            let mut edits = Vec::with_capacity(operations.len());
 1746
 1747                            if operations.is_empty() {
 1748                                zlog::trace!(
 1749                                    logger =>
 1750                                    "No changes for code action. Skipping {}",
 1751                                    describe_code_action(&action),
 1752                                );
 1753                                continue;
 1754                            }
 1755                            for operation in operations {
 1756                                let op = match operation {
 1757                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1758                                    lsp::DocumentChangeOperation::Op(_) => {
 1759                                        zlog::warn!(
 1760                                            logger =>
 1761                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1762                                            describe_code_action(&action),
 1763                                        );
 1764                                        continue 'actions;
 1765                                    }
 1766                                };
 1767                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1768                                    zlog::warn!(
 1769                                        logger =>
 1770                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1771                                        &op.text_document.uri,
 1772                                        describe_code_action(&action),
 1773                                    );
 1774                                    continue 'actions;
 1775                                };
 1776                                if &file_path != buffer_path_abs {
 1777                                    zlog::warn!(
 1778                                        logger =>
 1779                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1780                                        file_path,
 1781                                        buffer_path_abs,
 1782                                        describe_code_action(&action),
 1783                                    );
 1784                                    continue 'actions;
 1785                                }
 1786
 1787                                let mut lsp_edits = Vec::new();
 1788                                for edit in op.edits {
 1789                                    match edit {
 1790                                        Edit::Plain(edit) => {
 1791                                            if !lsp_edits.contains(&edit) {
 1792                                                lsp_edits.push(edit);
 1793                                            }
 1794                                        }
 1795                                        Edit::Annotated(edit) => {
 1796                                            if !lsp_edits.contains(&edit.text_edit) {
 1797                                                lsp_edits.push(edit.text_edit);
 1798                                            }
 1799                                        }
 1800                                        Edit::Snippet(_) => {
 1801                                            zlog::warn!(
 1802                                                logger =>
 1803                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1804                                                describe_code_action(&action),
 1805                                            );
 1806                                            continue 'actions;
 1807                                        }
 1808                                    }
 1809                                }
 1810                                let edits_result = lsp_store
 1811                                    .update(cx, |lsp_store, cx| {
 1812                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1813                                            &buffer.handle,
 1814                                            lsp_edits,
 1815                                            server.server_id(),
 1816                                            op.text_document.version,
 1817                                            cx,
 1818                                        )
 1819                                    })?
 1820                                    .await;
 1821                                let Ok(resolved_edits) = edits_result else {
 1822                                    zlog::warn!(
 1823                                        logger =>
 1824                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1825                                        buffer_path_abs.as_path(),
 1826                                        describe_code_action(&action),
 1827                                    );
 1828                                    continue 'actions;
 1829                                };
 1830                                edits.extend(resolved_edits);
 1831                            }
 1832
 1833                            if edits.is_empty() {
 1834                                zlog::warn!(logger => "No edits resolved from LSP");
 1835                                continue;
 1836                            }
 1837
 1838                            extend_formatting_transaction(
 1839                                buffer,
 1840                                formatting_transaction_id,
 1841                                cx,
 1842                                |buffer, cx| {
 1843                                    zlog::info!(
 1844                                        "Applying edits {edits:?}. Content: {:?}",
 1845                                        buffer.text()
 1846                                    );
 1847                                    buffer.edit(edits, None, cx);
 1848                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1849                                },
 1850                            )?;
 1851                        }
 1852
 1853                        if let Some(command) = action.lsp_action.command() {
 1854                            zlog::warn!(
 1855                                logger =>
 1856                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1857                                &command.command,
 1858                            );
 1859
 1860                            // bail early if command is invalid
 1861                            let server_capabilities = server.capabilities();
 1862                            let available_commands = server_capabilities
 1863                                .execute_command_provider
 1864                                .as_ref()
 1865                                .map(|options| options.commands.as_slice())
 1866                                .unwrap_or_default();
 1867                            if !available_commands.contains(&command.command) {
 1868                                zlog::warn!(
 1869                                    logger =>
 1870                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1871                                    command.command,
 1872                                    server.name(),
 1873                                );
 1874                                continue;
 1875                            }
 1876
 1877                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1878                            extend_formatting_transaction(
 1879                                buffer,
 1880                                formatting_transaction_id,
 1881                                cx,
 1882                                |_, _| {},
 1883                            )?;
 1884                            zlog::info!(logger => "Executing command {}", &command.command);
 1885
 1886                            lsp_store.update(cx, |this, _| {
 1887                                this.as_local_mut()
 1888                                    .unwrap()
 1889                                    .last_workspace_edits_by_language_server
 1890                                    .remove(&server.server_id());
 1891                            })?;
 1892
 1893                            let execute_command_result = server
 1894                                .request::<lsp::request::ExecuteCommand>(
 1895                                    lsp::ExecuteCommandParams {
 1896                                        command: command.command.clone(),
 1897                                        arguments: command.arguments.clone().unwrap_or_default(),
 1898                                        ..Default::default()
 1899                                    },
 1900                                )
 1901                                .await
 1902                                .into_response();
 1903
 1904                            if execute_command_result.is_err() {
 1905                                zlog::error!(
 1906                                    logger =>
 1907                                    "Failed to execute command '{}' as part of {}",
 1908                                    &command.command,
 1909                                    describe_code_action(&action),
 1910                                );
 1911                                continue 'actions;
 1912                            }
 1913
 1914                            let mut project_transaction_command =
 1915                                lsp_store.update(cx, |this, _| {
 1916                                    this.as_local_mut()
 1917                                        .unwrap()
 1918                                        .last_workspace_edits_by_language_server
 1919                                        .remove(&server.server_id())
 1920                                        .unwrap_or_default()
 1921                                })?;
 1922
 1923                            if let Some(transaction) =
 1924                                project_transaction_command.0.remove(&buffer.handle)
 1925                            {
 1926                                zlog::trace!(
 1927                                    logger =>
 1928                                    "Successfully captured {} edits that resulted from command {}",
 1929                                    transaction.edit_ids.len(),
 1930                                    &command.command,
 1931                                );
 1932                                let transaction_id_project_transaction = transaction.id;
 1933                                buffer.handle.update(cx, |buffer, _| {
 1934                                    // it may have been removed from history if push_to_history was
 1935                                    // false in deserialize_workspace_edit. If so push it so we
 1936                                    // can merge it with the format transaction
 1937                                    // and pop the combined transaction off the history stack
 1938                                    // later if push_to_history is false
 1939                                    if buffer.get_transaction(transaction.id).is_none() {
 1940                                        buffer.push_transaction(transaction, Instant::now());
 1941                                    }
 1942                                    buffer.merge_transactions(
 1943                                        transaction_id_project_transaction,
 1944                                        formatting_transaction_id,
 1945                                    );
 1946                                })?;
 1947                            }
 1948
 1949                            if !project_transaction_command.0.is_empty() {
 1950                                let mut extra_buffers = String::new();
 1951                                for buffer in project_transaction_command.0.keys() {
 1952                                    buffer
 1953                                        .read_with(cx, |b, cx| {
 1954                                            if let Some(path) = b.project_path(cx) {
 1955                                                if !extra_buffers.is_empty() {
 1956                                                    extra_buffers.push_str(", ");
 1957                                                }
 1958                                                extra_buffers.push_str(path.path.as_unix_str());
 1959                                            }
 1960                                        })
 1961                                        .ok();
 1962                                }
 1963                                zlog::warn!(
 1964                                    logger =>
 1965                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1966                                    &command.command,
 1967                                    extra_buffers,
 1968                                );
 1969                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1970                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1971                                // add it so it's included, and merge it into the format transaction when its created later
 1972                            }
 1973                        }
 1974                    }
 1975                }
 1976            }
 1977        }
 1978
 1979        Ok(())
 1980    }
 1981
 1982    pub async fn format_ranges_via_lsp(
 1983        this: &WeakEntity<LspStore>,
 1984        buffer_handle: &Entity<Buffer>,
 1985        ranges: &[Range<Anchor>],
 1986        abs_path: &Path,
 1987        language_server: &Arc<LanguageServer>,
 1988        settings: &LanguageSettings,
 1989        cx: &mut AsyncApp,
 1990    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1991        let capabilities = &language_server.capabilities();
 1992        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1993        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1994            anyhow::bail!(
 1995                "{} language server does not support range formatting",
 1996                language_server.name()
 1997            );
 1998        }
 1999
 2000        let uri = file_path_to_lsp_url(abs_path)?;
 2001        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2002
 2003        let lsp_edits = {
 2004            let mut lsp_ranges = Vec::new();
 2005            this.update(cx, |_this, cx| {
 2006                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2007                // not have been sent to the language server. This seems like a fairly systemic
 2008                // issue, though, the resolution probably is not specific to formatting.
 2009                //
 2010                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2011                // LSP.
 2012                let snapshot = buffer_handle.read(cx).snapshot();
 2013                for range in ranges {
 2014                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2015                }
 2016                anyhow::Ok(())
 2017            })??;
 2018
 2019            let mut edits = None;
 2020            for range in lsp_ranges {
 2021                if let Some(mut edit) = language_server
 2022                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2023                        text_document: text_document.clone(),
 2024                        range,
 2025                        options: lsp_command::lsp_formatting_options(settings),
 2026                        work_done_progress_params: Default::default(),
 2027                    })
 2028                    .await
 2029                    .into_response()?
 2030                {
 2031                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2032                }
 2033            }
 2034            edits
 2035        };
 2036
 2037        if let Some(lsp_edits) = lsp_edits {
 2038            this.update(cx, |this, cx| {
 2039                this.as_local_mut().unwrap().edits_from_lsp(
 2040                    buffer_handle,
 2041                    lsp_edits,
 2042                    language_server.server_id(),
 2043                    None,
 2044                    cx,
 2045                )
 2046            })?
 2047            .await
 2048        } else {
 2049            Ok(Vec::with_capacity(0))
 2050        }
 2051    }
 2052
 2053    async fn format_via_lsp(
 2054        this: &WeakEntity<LspStore>,
 2055        buffer: &Entity<Buffer>,
 2056        abs_path: &Path,
 2057        language_server: &Arc<LanguageServer>,
 2058        settings: &LanguageSettings,
 2059        cx: &mut AsyncApp,
 2060    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2061        let logger = zlog::scoped!("lsp_format");
 2062        zlog::debug!(logger => "Formatting via LSP");
 2063
 2064        let uri = file_path_to_lsp_url(abs_path)?;
 2065        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2066        let capabilities = &language_server.capabilities();
 2067
 2068        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2069        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2070
 2071        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2072            let _timer = zlog::time!(logger => "format-full");
 2073            language_server
 2074                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2075                    text_document,
 2076                    options: lsp_command::lsp_formatting_options(settings),
 2077                    work_done_progress_params: Default::default(),
 2078                })
 2079                .await
 2080                .into_response()?
 2081        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2082            let _timer = zlog::time!(logger => "format-range");
 2083            let buffer_start = lsp::Position::new(0, 0);
 2084            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2085            language_server
 2086                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2087                    text_document: text_document.clone(),
 2088                    range: lsp::Range::new(buffer_start, buffer_end),
 2089                    options: lsp_command::lsp_formatting_options(settings),
 2090                    work_done_progress_params: Default::default(),
 2091                })
 2092                .await
 2093                .into_response()?
 2094        } else {
 2095            None
 2096        };
 2097
 2098        if let Some(lsp_edits) = lsp_edits {
 2099            this.update(cx, |this, cx| {
 2100                this.as_local_mut().unwrap().edits_from_lsp(
 2101                    buffer,
 2102                    lsp_edits,
 2103                    language_server.server_id(),
 2104                    None,
 2105                    cx,
 2106                )
 2107            })?
 2108            .await
 2109        } else {
 2110            Ok(Vec::with_capacity(0))
 2111        }
 2112    }
 2113
 2114    async fn format_via_external_command(
 2115        buffer: &FormattableBuffer,
 2116        command: &str,
 2117        arguments: Option<&[String]>,
 2118        cx: &mut AsyncApp,
 2119    ) -> Result<Option<Diff>> {
 2120        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2121            let file = File::from_dyn(buffer.file())?;
 2122            let worktree = file.worktree.read(cx);
 2123            let mut worktree_path = worktree.abs_path().to_path_buf();
 2124            if worktree.root_entry()?.is_file() {
 2125                worktree_path.pop();
 2126            }
 2127            Some(worktree_path)
 2128        })?;
 2129
 2130        let mut child = util::command::new_smol_command(command);
 2131
 2132        if let Some(buffer_env) = buffer.env.as_ref() {
 2133            child.envs(buffer_env);
 2134        }
 2135
 2136        if let Some(working_dir_path) = working_dir_path {
 2137            child.current_dir(working_dir_path);
 2138        }
 2139
 2140        if let Some(arguments) = arguments {
 2141            child.args(arguments.iter().map(|arg| {
 2142                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2143                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2144                } else {
 2145                    arg.replace("{buffer_path}", "Untitled")
 2146                }
 2147            }));
 2148        }
 2149
 2150        let mut child = child
 2151            .stdin(smol::process::Stdio::piped())
 2152            .stdout(smol::process::Stdio::piped())
 2153            .stderr(smol::process::Stdio::piped())
 2154            .spawn()?;
 2155
 2156        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2157        let text = buffer
 2158            .handle
 2159            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2160        for chunk in text.chunks() {
 2161            stdin.write_all(chunk.as_bytes()).await?;
 2162        }
 2163        stdin.flush().await?;
 2164
 2165        let output = child.output().await?;
 2166        anyhow::ensure!(
 2167            output.status.success(),
 2168            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2169            output.status.code(),
 2170            String::from_utf8_lossy(&output.stdout),
 2171            String::from_utf8_lossy(&output.stderr),
 2172        );
 2173
 2174        let stdout = String::from_utf8(output.stdout)?;
 2175        Ok(Some(
 2176            buffer
 2177                .handle
 2178                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2179                .await,
 2180        ))
 2181    }
 2182
 2183    async fn try_resolve_code_action(
 2184        lang_server: &LanguageServer,
 2185        action: &mut CodeAction,
 2186    ) -> anyhow::Result<()> {
 2187        match &mut action.lsp_action {
 2188            LspAction::Action(lsp_action) => {
 2189                if !action.resolved
 2190                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2191                    && lsp_action.data.is_some()
 2192                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2193                {
 2194                    *lsp_action = Box::new(
 2195                        lang_server
 2196                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2197                            .await
 2198                            .into_response()?,
 2199                    );
 2200                }
 2201            }
 2202            LspAction::CodeLens(lens) => {
 2203                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2204                    *lens = lang_server
 2205                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2206                        .await
 2207                        .into_response()?;
 2208                }
 2209            }
 2210            LspAction::Command(_) => {}
 2211        }
 2212
 2213        action.resolved = true;
 2214        anyhow::Ok(())
 2215    }
 2216
 2217    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2218        let buffer = buffer_handle.read(cx);
 2219
 2220        let file = buffer.file().cloned();
 2221
 2222        let Some(file) = File::from_dyn(file.as_ref()) else {
 2223            return;
 2224        };
 2225        if !file.is_local() {
 2226            return;
 2227        }
 2228        let path = ProjectPath::from_file(file, cx);
 2229        let worktree_id = file.worktree_id(cx);
 2230        let language = buffer.language().cloned();
 2231
 2232        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2233            for (server_id, diagnostics) in
 2234                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2235            {
 2236                self.update_buffer_diagnostics(
 2237                    buffer_handle,
 2238                    server_id,
 2239                    None,
 2240                    None,
 2241                    diagnostics,
 2242                    Vec::new(),
 2243                    cx,
 2244                )
 2245                .log_err();
 2246            }
 2247        }
 2248        let Some(language) = language else {
 2249            return;
 2250        };
 2251        let Some(snapshot) = self
 2252            .worktree_store
 2253            .read(cx)
 2254            .worktree_for_id(worktree_id, cx)
 2255            .map(|worktree| worktree.read(cx).snapshot())
 2256        else {
 2257            return;
 2258        };
 2259        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2260
 2261        for server_id in
 2262            self.lsp_tree
 2263                .get(path, language.name(), language.manifest(), &delegate, cx)
 2264        {
 2265            let server = self
 2266                .language_servers
 2267                .get(&server_id)
 2268                .and_then(|server_state| {
 2269                    if let LanguageServerState::Running { server, .. } = server_state {
 2270                        Some(server.clone())
 2271                    } else {
 2272                        None
 2273                    }
 2274                });
 2275            let server = match server {
 2276                Some(server) => server,
 2277                None => continue,
 2278            };
 2279
 2280            buffer_handle.update(cx, |buffer, cx| {
 2281                buffer.set_completion_triggers(
 2282                    server.server_id(),
 2283                    server
 2284                        .capabilities()
 2285                        .completion_provider
 2286                        .as_ref()
 2287                        .and_then(|provider| {
 2288                            provider
 2289                                .trigger_characters
 2290                                .as_ref()
 2291                                .map(|characters| characters.iter().cloned().collect())
 2292                        })
 2293                        .unwrap_or_default(),
 2294                    cx,
 2295                );
 2296            });
 2297        }
 2298    }
 2299
 2300    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2301        buffer.update(cx, |buffer, cx| {
 2302            let Some(language) = buffer.language() else {
 2303                return;
 2304            };
 2305            let path = ProjectPath {
 2306                worktree_id: old_file.worktree_id(cx),
 2307                path: old_file.path.clone(),
 2308            };
 2309            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2310                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2311                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2312            }
 2313        });
 2314    }
 2315
 2316    fn update_buffer_diagnostics(
 2317        &mut self,
 2318        buffer: &Entity<Buffer>,
 2319        server_id: LanguageServerId,
 2320        result_id: Option<String>,
 2321        version: Option<i32>,
 2322        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2323        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2324        cx: &mut Context<LspStore>,
 2325    ) -> Result<()> {
 2326        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2327            Ordering::Equal
 2328                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2329                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2330                .then_with(|| a.severity.cmp(&b.severity))
 2331                .then_with(|| a.message.cmp(&b.message))
 2332        }
 2333
 2334        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2335        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2336        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2337
 2338        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2339            Ordering::Equal
 2340                .then_with(|| a.range.start.cmp(&b.range.start))
 2341                .then_with(|| b.range.end.cmp(&a.range.end))
 2342                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2343        });
 2344
 2345        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2346
 2347        let edits_since_save = std::cell::LazyCell::new(|| {
 2348            let saved_version = buffer.read(cx).saved_version();
 2349            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2350        });
 2351
 2352        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2353
 2354        for (new_diagnostic, entry) in diagnostics {
 2355            let start;
 2356            let end;
 2357            if new_diagnostic && entry.diagnostic.is_disk_based {
 2358                // Some diagnostics are based on files on disk instead of buffers'
 2359                // current contents. Adjust these diagnostics' ranges to reflect
 2360                // any unsaved edits.
 2361                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2362                // and were properly adjusted on reuse.
 2363                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2364                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2365            } else {
 2366                start = entry.range.start;
 2367                end = entry.range.end;
 2368            }
 2369
 2370            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2371                ..snapshot.clip_point_utf16(end, Bias::Right);
 2372
 2373            // Expand empty ranges by one codepoint
 2374            if range.start == range.end {
 2375                // This will be go to the next boundary when being clipped
 2376                range.end.column += 1;
 2377                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2378                if range.start == range.end && range.end.column > 0 {
 2379                    range.start.column -= 1;
 2380                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2381                }
 2382            }
 2383
 2384            sanitized_diagnostics.push(DiagnosticEntry {
 2385                range,
 2386                diagnostic: entry.diagnostic,
 2387            });
 2388        }
 2389        drop(edits_since_save);
 2390
 2391        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2392        buffer.update(cx, |buffer, cx| {
 2393            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2394                self.buffer_pull_diagnostics_result_ids
 2395                    .entry(server_id)
 2396                    .or_default()
 2397                    .insert(abs_path, result_id);
 2398            }
 2399
 2400            buffer.update_diagnostics(server_id, set, cx)
 2401        });
 2402
 2403        Ok(())
 2404    }
 2405
 2406    fn register_language_server_for_invisible_worktree(
 2407        &mut self,
 2408        worktree: &Entity<Worktree>,
 2409        language_server_id: LanguageServerId,
 2410        cx: &mut App,
 2411    ) {
 2412        let worktree = worktree.read(cx);
 2413        let worktree_id = worktree.id();
 2414        debug_assert!(!worktree.is_visible());
 2415        let Some(mut origin_seed) = self
 2416            .language_server_ids
 2417            .iter()
 2418            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2419        else {
 2420            return;
 2421        };
 2422        origin_seed.worktree_id = worktree_id;
 2423        self.language_server_ids
 2424            .entry(origin_seed)
 2425            .or_insert_with(|| UnifiedLanguageServer {
 2426                id: language_server_id,
 2427                project_roots: Default::default(),
 2428            });
 2429    }
 2430
 2431    fn register_buffer_with_language_servers(
 2432        &mut self,
 2433        buffer_handle: &Entity<Buffer>,
 2434        only_register_servers: HashSet<LanguageServerSelector>,
 2435        cx: &mut Context<LspStore>,
 2436    ) {
 2437        let buffer = buffer_handle.read(cx);
 2438        let buffer_id = buffer.remote_id();
 2439
 2440        let Some(file) = File::from_dyn(buffer.file()) else {
 2441            return;
 2442        };
 2443        if !file.is_local() {
 2444            return;
 2445        }
 2446
 2447        let abs_path = file.abs_path(cx);
 2448        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2449            return;
 2450        };
 2451        let initial_snapshot = buffer.text_snapshot();
 2452        let worktree_id = file.worktree_id(cx);
 2453
 2454        let Some(language) = buffer.language().cloned() else {
 2455            return;
 2456        };
 2457        let path: Arc<RelPath> = file
 2458            .path()
 2459            .parent()
 2460            .map(Arc::from)
 2461            .unwrap_or_else(|| file.path().clone());
 2462        let Some(worktree) = self
 2463            .worktree_store
 2464            .read(cx)
 2465            .worktree_for_id(worktree_id, cx)
 2466        else {
 2467            return;
 2468        };
 2469        let language_name = language.name();
 2470        let (reused, delegate, servers) = self
 2471            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2472            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2473            .unwrap_or_else(|| {
 2474                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2475                let delegate: Arc<dyn ManifestDelegate> =
 2476                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2477
 2478                let servers = self
 2479                    .lsp_tree
 2480                    .walk(
 2481                        ProjectPath { worktree_id, path },
 2482                        language.name(),
 2483                        language.manifest(),
 2484                        &delegate,
 2485                        cx,
 2486                    )
 2487                    .collect::<Vec<_>>();
 2488                (false, lsp_delegate, servers)
 2489            });
 2490        let servers_and_adapters = servers
 2491            .into_iter()
 2492            .filter_map(|server_node| {
 2493                if reused && server_node.server_id().is_none() {
 2494                    return None;
 2495                }
 2496                if !only_register_servers.is_empty() {
 2497                    if let Some(server_id) = server_node.server_id()
 2498                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2499                    {
 2500                        return None;
 2501                    }
 2502                    if let Some(name) = server_node.name()
 2503                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2504                    {
 2505                        return None;
 2506                    }
 2507                }
 2508
 2509                let server_id = server_node.server_id_or_init(|disposition| {
 2510                    let path = &disposition.path;
 2511
 2512                    {
 2513                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2514
 2515                        let server_id = self.get_or_insert_language_server(
 2516                            &worktree,
 2517                            delegate.clone(),
 2518                            disposition,
 2519                            &language_name,
 2520                            cx,
 2521                        );
 2522
 2523                        if let Some(state) = self.language_servers.get(&server_id)
 2524                            && let Ok(uri) = uri
 2525                        {
 2526                            state.add_workspace_folder(uri);
 2527                        };
 2528                        server_id
 2529                    }
 2530                })?;
 2531                let server_state = self.language_servers.get(&server_id)?;
 2532                if let LanguageServerState::Running {
 2533                    server, adapter, ..
 2534                } = server_state
 2535                {
 2536                    Some((server.clone(), adapter.clone()))
 2537                } else {
 2538                    None
 2539                }
 2540            })
 2541            .collect::<Vec<_>>();
 2542        for (server, adapter) in servers_and_adapters {
 2543            buffer_handle.update(cx, |buffer, cx| {
 2544                buffer.set_completion_triggers(
 2545                    server.server_id(),
 2546                    server
 2547                        .capabilities()
 2548                        .completion_provider
 2549                        .as_ref()
 2550                        .and_then(|provider| {
 2551                            provider
 2552                                .trigger_characters
 2553                                .as_ref()
 2554                                .map(|characters| characters.iter().cloned().collect())
 2555                        })
 2556                        .unwrap_or_default(),
 2557                    cx,
 2558                );
 2559            });
 2560
 2561            let snapshot = LspBufferSnapshot {
 2562                version: 0,
 2563                snapshot: initial_snapshot.clone(),
 2564            };
 2565
 2566            let mut registered = false;
 2567            self.buffer_snapshots
 2568                .entry(buffer_id)
 2569                .or_default()
 2570                .entry(server.server_id())
 2571                .or_insert_with(|| {
 2572                    registered = true;
 2573                    server.register_buffer(
 2574                        uri.clone(),
 2575                        adapter.language_id(&language.name()),
 2576                        0,
 2577                        initial_snapshot.text(),
 2578                    );
 2579
 2580                    vec![snapshot]
 2581                });
 2582
 2583            self.buffers_opened_in_servers
 2584                .entry(buffer_id)
 2585                .or_default()
 2586                .insert(server.server_id());
 2587            if registered {
 2588                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2589                    language_server_id: server.server_id(),
 2590                    name: None,
 2591                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2592                        proto::RegisteredForBuffer {
 2593                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2594                            buffer_id: buffer_id.to_proto(),
 2595                        },
 2596                    ),
 2597                });
 2598            }
 2599        }
 2600    }
 2601
 2602    fn reuse_existing_language_server<'lang_name>(
 2603        &self,
 2604        server_tree: &LanguageServerTree,
 2605        worktree: &Entity<Worktree>,
 2606        language_name: &'lang_name LanguageName,
 2607        cx: &mut App,
 2608    ) -> Option<(
 2609        Arc<LocalLspAdapterDelegate>,
 2610        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2611    )> {
 2612        if worktree.read(cx).is_visible() {
 2613            return None;
 2614        }
 2615
 2616        let worktree_store = self.worktree_store.read(cx);
 2617        let servers = server_tree
 2618            .instances
 2619            .iter()
 2620            .filter(|(worktree_id, _)| {
 2621                worktree_store
 2622                    .worktree_for_id(**worktree_id, cx)
 2623                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2624            })
 2625            .flat_map(|(worktree_id, servers)| {
 2626                servers
 2627                    .roots
 2628                    .iter()
 2629                    .flat_map(|(_, language_servers)| language_servers)
 2630                    .map(move |(_, (server_node, server_languages))| {
 2631                        (worktree_id, server_node, server_languages)
 2632                    })
 2633                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2634                    .map(|(worktree_id, server_node, _)| {
 2635                        (
 2636                            *worktree_id,
 2637                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2638                        )
 2639                    })
 2640            })
 2641            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2642                acc.entry(worktree_id)
 2643                    .or_insert_with(Vec::new)
 2644                    .push(server_node);
 2645                acc
 2646            })
 2647            .into_values()
 2648            .max_by_key(|servers| servers.len())?;
 2649
 2650        let worktree_id = worktree.read(cx).id();
 2651        let apply = move |tree: &mut LanguageServerTree| {
 2652            for server_node in &servers {
 2653                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2654            }
 2655            servers
 2656        };
 2657
 2658        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2659        Some((delegate, apply))
 2660    }
 2661
 2662    pub(crate) fn unregister_old_buffer_from_language_servers(
 2663        &mut self,
 2664        buffer: &Entity<Buffer>,
 2665        old_file: &File,
 2666        cx: &mut App,
 2667    ) {
 2668        let old_path = match old_file.as_local() {
 2669            Some(local) => local.abs_path(cx),
 2670            None => return,
 2671        };
 2672
 2673        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2674            debug_panic!("{old_path:?} is not parseable as an URI");
 2675            return;
 2676        };
 2677        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2678    }
 2679
 2680    pub(crate) fn unregister_buffer_from_language_servers(
 2681        &mut self,
 2682        buffer: &Entity<Buffer>,
 2683        file_url: &lsp::Uri,
 2684        cx: &mut App,
 2685    ) {
 2686        buffer.update(cx, |buffer, cx| {
 2687            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2688
 2689            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2690                language_server.unregister_buffer(file_url.clone());
 2691            }
 2692        });
 2693    }
 2694
 2695    fn buffer_snapshot_for_lsp_version(
 2696        &mut self,
 2697        buffer: &Entity<Buffer>,
 2698        server_id: LanguageServerId,
 2699        version: Option<i32>,
 2700        cx: &App,
 2701    ) -> Result<TextBufferSnapshot> {
 2702        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2703
 2704        if let Some(version) = version {
 2705            let buffer_id = buffer.read(cx).remote_id();
 2706            let snapshots = if let Some(snapshots) = self
 2707                .buffer_snapshots
 2708                .get_mut(&buffer_id)
 2709                .and_then(|m| m.get_mut(&server_id))
 2710            {
 2711                snapshots
 2712            } else if version == 0 {
 2713                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2714                // We detect this case and treat it as if the version was `None`.
 2715                return Ok(buffer.read(cx).text_snapshot());
 2716            } else {
 2717                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2718            };
 2719
 2720            let found_snapshot = snapshots
 2721                    .binary_search_by_key(&version, |e| e.version)
 2722                    .map(|ix| snapshots[ix].snapshot.clone())
 2723                    .map_err(|_| {
 2724                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2725                    })?;
 2726
 2727            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2728            Ok(found_snapshot)
 2729        } else {
 2730            Ok((buffer.read(cx)).text_snapshot())
 2731        }
 2732    }
 2733
 2734    async fn get_server_code_actions_from_action_kinds(
 2735        lsp_store: &WeakEntity<LspStore>,
 2736        language_server_id: LanguageServerId,
 2737        code_action_kinds: Vec<lsp::CodeActionKind>,
 2738        buffer: &Entity<Buffer>,
 2739        cx: &mut AsyncApp,
 2740    ) -> Result<Vec<CodeAction>> {
 2741        let actions = lsp_store
 2742            .update(cx, move |this, cx| {
 2743                let request = GetCodeActions {
 2744                    range: text::Anchor::MIN..text::Anchor::MAX,
 2745                    kinds: Some(code_action_kinds),
 2746                };
 2747                let server = LanguageServerToQuery::Other(language_server_id);
 2748                this.request_lsp(buffer.clone(), server, request, cx)
 2749            })?
 2750            .await?;
 2751        Ok(actions)
 2752    }
 2753
 2754    pub async fn execute_code_actions_on_server(
 2755        lsp_store: &WeakEntity<LspStore>,
 2756        language_server: &Arc<LanguageServer>,
 2757
 2758        actions: Vec<CodeAction>,
 2759        push_to_history: bool,
 2760        project_transaction: &mut ProjectTransaction,
 2761        cx: &mut AsyncApp,
 2762    ) -> anyhow::Result<()> {
 2763        for mut action in actions {
 2764            Self::try_resolve_code_action(language_server, &mut action)
 2765                .await
 2766                .context("resolving a formatting code action")?;
 2767
 2768            if let Some(edit) = action.lsp_action.edit() {
 2769                if edit.changes.is_none() && edit.document_changes.is_none() {
 2770                    continue;
 2771                }
 2772
 2773                let new = Self::deserialize_workspace_edit(
 2774                    lsp_store.upgrade().context("project dropped")?,
 2775                    edit.clone(),
 2776                    push_to_history,
 2777                    language_server.clone(),
 2778                    cx,
 2779                )
 2780                .await?;
 2781                project_transaction.0.extend(new.0);
 2782            }
 2783
 2784            if let Some(command) = action.lsp_action.command() {
 2785                let server_capabilities = language_server.capabilities();
 2786                let available_commands = server_capabilities
 2787                    .execute_command_provider
 2788                    .as_ref()
 2789                    .map(|options| options.commands.as_slice())
 2790                    .unwrap_or_default();
 2791                if available_commands.contains(&command.command) {
 2792                    lsp_store.update(cx, |lsp_store, _| {
 2793                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2794                            mode.last_workspace_edits_by_language_server
 2795                                .remove(&language_server.server_id());
 2796                        }
 2797                    })?;
 2798
 2799                    language_server
 2800                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2801                            command: command.command.clone(),
 2802                            arguments: command.arguments.clone().unwrap_or_default(),
 2803                            ..Default::default()
 2804                        })
 2805                        .await
 2806                        .into_response()
 2807                        .context("execute command")?;
 2808
 2809                    lsp_store.update(cx, |this, _| {
 2810                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2811                            project_transaction.0.extend(
 2812                                mode.last_workspace_edits_by_language_server
 2813                                    .remove(&language_server.server_id())
 2814                                    .unwrap_or_default()
 2815                                    .0,
 2816                            )
 2817                        }
 2818                    })?;
 2819                } else {
 2820                    log::warn!(
 2821                        "Cannot execute a command {} not listed in the language server capabilities",
 2822                        command.command
 2823                    )
 2824                }
 2825            }
 2826        }
 2827        Ok(())
 2828    }
 2829
 2830    pub async fn deserialize_text_edits(
 2831        this: Entity<LspStore>,
 2832        buffer_to_edit: Entity<Buffer>,
 2833        edits: Vec<lsp::TextEdit>,
 2834        push_to_history: bool,
 2835        _: Arc<CachedLspAdapter>,
 2836        language_server: Arc<LanguageServer>,
 2837        cx: &mut AsyncApp,
 2838    ) -> Result<Option<Transaction>> {
 2839        let edits = this
 2840            .update(cx, |this, cx| {
 2841                this.as_local_mut().unwrap().edits_from_lsp(
 2842                    &buffer_to_edit,
 2843                    edits,
 2844                    language_server.server_id(),
 2845                    None,
 2846                    cx,
 2847                )
 2848            })?
 2849            .await?;
 2850
 2851        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2852            buffer.finalize_last_transaction();
 2853            buffer.start_transaction();
 2854            for (range, text) in edits {
 2855                buffer.edit([(range, text)], None, cx);
 2856            }
 2857
 2858            if buffer.end_transaction(cx).is_some() {
 2859                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2860                if !push_to_history {
 2861                    buffer.forget_transaction(transaction.id);
 2862                }
 2863                Some(transaction)
 2864            } else {
 2865                None
 2866            }
 2867        })?;
 2868
 2869        Ok(transaction)
 2870    }
 2871
 2872    #[allow(clippy::type_complexity)]
 2873    pub(crate) fn edits_from_lsp(
 2874        &mut self,
 2875        buffer: &Entity<Buffer>,
 2876        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2877        server_id: LanguageServerId,
 2878        version: Option<i32>,
 2879        cx: &mut Context<LspStore>,
 2880    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2881        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2882        cx.background_spawn(async move {
 2883            let snapshot = snapshot?;
 2884            let mut lsp_edits = lsp_edits
 2885                .into_iter()
 2886                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2887                .collect::<Vec<_>>();
 2888
 2889            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2890
 2891            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2892            let mut edits = Vec::new();
 2893            while let Some((range, mut new_text)) = lsp_edits.next() {
 2894                // Clip invalid ranges provided by the language server.
 2895                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2896                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2897
 2898                // Combine any LSP edits that are adjacent.
 2899                //
 2900                // Also, combine LSP edits that are separated from each other by only
 2901                // a newline. This is important because for some code actions,
 2902                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2903                // are separated by unchanged newline characters.
 2904                //
 2905                // In order for the diffing logic below to work properly, any edits that
 2906                // cancel each other out must be combined into one.
 2907                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2908                    if next_range.start.0 > range.end {
 2909                        if next_range.start.0.row > range.end.row + 1
 2910                            || next_range.start.0.column > 0
 2911                            || snapshot.clip_point_utf16(
 2912                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2913                                Bias::Left,
 2914                            ) > range.end
 2915                        {
 2916                            break;
 2917                        }
 2918                        new_text.push('\n');
 2919                    }
 2920                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2921                    new_text.push_str(next_text);
 2922                    lsp_edits.next();
 2923                }
 2924
 2925                // For multiline edits, perform a diff of the old and new text so that
 2926                // we can identify the changes more precisely, preserving the locations
 2927                // of any anchors positioned in the unchanged regions.
 2928                if range.end.row > range.start.row {
 2929                    let offset = range.start.to_offset(&snapshot);
 2930                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2931                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2932                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2933                        (
 2934                            snapshot.anchor_after(offset + range.start)
 2935                                ..snapshot.anchor_before(offset + range.end),
 2936                            replacement,
 2937                        )
 2938                    }));
 2939                } else if range.end == range.start {
 2940                    let anchor = snapshot.anchor_after(range.start);
 2941                    edits.push((anchor..anchor, new_text.into()));
 2942                } else {
 2943                    let edit_start = snapshot.anchor_after(range.start);
 2944                    let edit_end = snapshot.anchor_before(range.end);
 2945                    edits.push((edit_start..edit_end, new_text.into()));
 2946                }
 2947            }
 2948
 2949            Ok(edits)
 2950        })
 2951    }
 2952
 2953    pub(crate) async fn deserialize_workspace_edit(
 2954        this: Entity<LspStore>,
 2955        edit: lsp::WorkspaceEdit,
 2956        push_to_history: bool,
 2957        language_server: Arc<LanguageServer>,
 2958        cx: &mut AsyncApp,
 2959    ) -> Result<ProjectTransaction> {
 2960        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2961
 2962        let mut operations = Vec::new();
 2963        if let Some(document_changes) = edit.document_changes {
 2964            match document_changes {
 2965                lsp::DocumentChanges::Edits(edits) => {
 2966                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2967                }
 2968                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2969            }
 2970        } else if let Some(changes) = edit.changes {
 2971            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2972                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2973                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2974                        uri,
 2975                        version: None,
 2976                    },
 2977                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2978                })
 2979            }));
 2980        }
 2981
 2982        let mut project_transaction = ProjectTransaction::default();
 2983        for operation in operations {
 2984            match operation {
 2985                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2986                    let abs_path = op
 2987                        .uri
 2988                        .to_file_path()
 2989                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2990
 2991                    if let Some(parent_path) = abs_path.parent() {
 2992                        fs.create_dir(parent_path).await?;
 2993                    }
 2994                    if abs_path.ends_with("/") {
 2995                        fs.create_dir(&abs_path).await?;
 2996                    } else {
 2997                        fs.create_file(
 2998                            &abs_path,
 2999                            op.options
 3000                                .map(|options| fs::CreateOptions {
 3001                                    overwrite: options.overwrite.unwrap_or(false),
 3002                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3003                                })
 3004                                .unwrap_or_default(),
 3005                        )
 3006                        .await?;
 3007                    }
 3008                }
 3009
 3010                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3011                    let source_abs_path = op
 3012                        .old_uri
 3013                        .to_file_path()
 3014                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3015                    let target_abs_path = op
 3016                        .new_uri
 3017                        .to_file_path()
 3018                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3019                    fs.rename(
 3020                        &source_abs_path,
 3021                        &target_abs_path,
 3022                        op.options
 3023                            .map(|options| fs::RenameOptions {
 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                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3033                    let abs_path = op
 3034                        .uri
 3035                        .to_file_path()
 3036                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3037                    let options = op
 3038                        .options
 3039                        .map(|options| fs::RemoveOptions {
 3040                            recursive: options.recursive.unwrap_or(false),
 3041                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3042                        })
 3043                        .unwrap_or_default();
 3044                    if abs_path.ends_with("/") {
 3045                        fs.remove_dir(&abs_path, options).await?;
 3046                    } else {
 3047                        fs.remove_file(&abs_path, options).await?;
 3048                    }
 3049                }
 3050
 3051                lsp::DocumentChangeOperation::Edit(op) => {
 3052                    let buffer_to_edit = this
 3053                        .update(cx, |this, cx| {
 3054                            this.open_local_buffer_via_lsp(
 3055                                op.text_document.uri.clone(),
 3056                                language_server.server_id(),
 3057                                cx,
 3058                            )
 3059                        })?
 3060                        .await?;
 3061
 3062                    let edits = this
 3063                        .update(cx, |this, cx| {
 3064                            let path = buffer_to_edit.read(cx).project_path(cx);
 3065                            let active_entry = this.active_entry;
 3066                            let is_active_entry = path.is_some_and(|project_path| {
 3067                                this.worktree_store
 3068                                    .read(cx)
 3069                                    .entry_for_path(&project_path, cx)
 3070                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3071                            });
 3072                            let local = this.as_local_mut().unwrap();
 3073
 3074                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3075                            for edit in op.edits {
 3076                                match edit {
 3077                                    Edit::Plain(edit) => {
 3078                                        if !edits.contains(&edit) {
 3079                                            edits.push(edit)
 3080                                        }
 3081                                    }
 3082                                    Edit::Annotated(edit) => {
 3083                                        if !edits.contains(&edit.text_edit) {
 3084                                            edits.push(edit.text_edit)
 3085                                        }
 3086                                    }
 3087                                    Edit::Snippet(edit) => {
 3088                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3089                                        else {
 3090                                            continue;
 3091                                        };
 3092
 3093                                        if is_active_entry {
 3094                                            snippet_edits.push((edit.range, snippet));
 3095                                        } else {
 3096                                            // Since this buffer is not focused, apply a normal edit.
 3097                                            let new_edit = TextEdit {
 3098                                                range: edit.range,
 3099                                                new_text: snippet.text,
 3100                                            };
 3101                                            if !edits.contains(&new_edit) {
 3102                                                edits.push(new_edit);
 3103                                            }
 3104                                        }
 3105                                    }
 3106                                }
 3107                            }
 3108                            if !snippet_edits.is_empty() {
 3109                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3110                                let version = if let Some(buffer_version) = op.text_document.version
 3111                                {
 3112                                    local
 3113                                        .buffer_snapshot_for_lsp_version(
 3114                                            &buffer_to_edit,
 3115                                            language_server.server_id(),
 3116                                            Some(buffer_version),
 3117                                            cx,
 3118                                        )
 3119                                        .ok()
 3120                                        .map(|snapshot| snapshot.version)
 3121                                } else {
 3122                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3123                                };
 3124
 3125                                let most_recent_edit =
 3126                                    version.and_then(|version| version.most_recent());
 3127                                // Check if the edit that triggered that edit has been made by this participant.
 3128
 3129                                if let Some(most_recent_edit) = most_recent_edit {
 3130                                    cx.emit(LspStoreEvent::SnippetEdit {
 3131                                        buffer_id,
 3132                                        edits: snippet_edits,
 3133                                        most_recent_edit,
 3134                                    });
 3135                                }
 3136                            }
 3137
 3138                            local.edits_from_lsp(
 3139                                &buffer_to_edit,
 3140                                edits,
 3141                                language_server.server_id(),
 3142                                op.text_document.version,
 3143                                cx,
 3144                            )
 3145                        })?
 3146                        .await?;
 3147
 3148                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3149                        buffer.finalize_last_transaction();
 3150                        buffer.start_transaction();
 3151                        for (range, text) in edits {
 3152                            buffer.edit([(range, text)], None, cx);
 3153                        }
 3154
 3155                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3156                            if push_to_history {
 3157                                buffer.finalize_last_transaction();
 3158                                buffer.get_transaction(transaction_id).cloned()
 3159                            } else {
 3160                                buffer.forget_transaction(transaction_id)
 3161                            }
 3162                        })
 3163                    })?;
 3164                    if let Some(transaction) = transaction {
 3165                        project_transaction.0.insert(buffer_to_edit, transaction);
 3166                    }
 3167                }
 3168            }
 3169        }
 3170
 3171        Ok(project_transaction)
 3172    }
 3173
 3174    async fn on_lsp_workspace_edit(
 3175        this: WeakEntity<LspStore>,
 3176        params: lsp::ApplyWorkspaceEditParams,
 3177        server_id: LanguageServerId,
 3178        cx: &mut AsyncApp,
 3179    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3180        let this = this.upgrade().context("project project closed")?;
 3181        let language_server = this
 3182            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3183            .context("language server not found")?;
 3184        let transaction = Self::deserialize_workspace_edit(
 3185            this.clone(),
 3186            params.edit,
 3187            true,
 3188            language_server.clone(),
 3189            cx,
 3190        )
 3191        .await
 3192        .log_err();
 3193        this.update(cx, |this, _| {
 3194            if let Some(transaction) = transaction {
 3195                this.as_local_mut()
 3196                    .unwrap()
 3197                    .last_workspace_edits_by_language_server
 3198                    .insert(server_id, transaction);
 3199            }
 3200        })?;
 3201        Ok(lsp::ApplyWorkspaceEditResponse {
 3202            applied: true,
 3203            failed_change: None,
 3204            failure_reason: None,
 3205        })
 3206    }
 3207
 3208    fn remove_worktree(
 3209        &mut self,
 3210        id_to_remove: WorktreeId,
 3211        cx: &mut Context<LspStore>,
 3212    ) -> Vec<LanguageServerId> {
 3213        self.diagnostics.remove(&id_to_remove);
 3214        self.prettier_store.update(cx, |prettier_store, cx| {
 3215            prettier_store.remove_worktree(id_to_remove, cx);
 3216        });
 3217
 3218        let mut servers_to_remove = BTreeSet::default();
 3219        let mut servers_to_preserve = HashSet::default();
 3220        for (seed, state) in &self.language_server_ids {
 3221            if seed.worktree_id == id_to_remove {
 3222                servers_to_remove.insert(state.id);
 3223            } else {
 3224                servers_to_preserve.insert(state.id);
 3225            }
 3226        }
 3227        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3228        self.language_server_ids
 3229            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3230        for server_id_to_remove in &servers_to_remove {
 3231            self.language_server_watched_paths
 3232                .remove(server_id_to_remove);
 3233            self.language_server_paths_watched_for_rename
 3234                .remove(server_id_to_remove);
 3235            self.last_workspace_edits_by_language_server
 3236                .remove(server_id_to_remove);
 3237            self.language_servers.remove(server_id_to_remove);
 3238            self.buffer_pull_diagnostics_result_ids
 3239                .remove(server_id_to_remove);
 3240            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3241                buffer_servers.remove(server_id_to_remove);
 3242            }
 3243            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3244        }
 3245        servers_to_remove.into_iter().collect()
 3246    }
 3247
 3248    fn rebuild_watched_paths_inner<'a>(
 3249        &'a self,
 3250        language_server_id: LanguageServerId,
 3251        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3252        cx: &mut Context<LspStore>,
 3253    ) -> LanguageServerWatchedPathsBuilder {
 3254        let worktrees = self
 3255            .worktree_store
 3256            .read(cx)
 3257            .worktrees()
 3258            .filter_map(|worktree| {
 3259                self.language_servers_for_worktree(worktree.read(cx).id())
 3260                    .find(|server| server.server_id() == language_server_id)
 3261                    .map(|_| worktree)
 3262            })
 3263            .collect::<Vec<_>>();
 3264
 3265        let mut worktree_globs = HashMap::default();
 3266        let mut abs_globs = HashMap::default();
 3267        log::trace!(
 3268            "Processing new watcher paths for language server with id {}",
 3269            language_server_id
 3270        );
 3271
 3272        for watcher in watchers {
 3273            if let Some((worktree, literal_prefix, pattern)) =
 3274                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3275            {
 3276                worktree.update(cx, |worktree, _| {
 3277                    if let Some((tree, glob)) =
 3278                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3279                    {
 3280                        tree.add_path_prefix_to_scan(literal_prefix);
 3281                        worktree_globs
 3282                            .entry(tree.id())
 3283                            .or_insert_with(GlobSetBuilder::new)
 3284                            .add(glob);
 3285                    }
 3286                });
 3287            } else {
 3288                let (path, pattern) = match &watcher.glob_pattern {
 3289                    lsp::GlobPattern::String(s) => {
 3290                        let watcher_path = SanitizedPath::new(s);
 3291                        let path = glob_literal_prefix(watcher_path.as_path());
 3292                        let pattern = watcher_path
 3293                            .as_path()
 3294                            .strip_prefix(&path)
 3295                            .map(|p| p.to_string_lossy().into_owned())
 3296                            .unwrap_or_else(|e| {
 3297                                debug_panic!(
 3298                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3299                                    s,
 3300                                    path.display(),
 3301                                    e
 3302                                );
 3303                                watcher_path.as_path().to_string_lossy().into_owned()
 3304                            });
 3305                        (path, pattern)
 3306                    }
 3307                    lsp::GlobPattern::Relative(rp) => {
 3308                        let Ok(mut base_uri) = match &rp.base_uri {
 3309                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3310                            lsp::OneOf::Right(base_uri) => base_uri,
 3311                        }
 3312                        .to_file_path() else {
 3313                            continue;
 3314                        };
 3315
 3316                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3317                        let pattern = Path::new(&rp.pattern)
 3318                            .strip_prefix(&path)
 3319                            .map(|p| p.to_string_lossy().into_owned())
 3320                            .unwrap_or_else(|e| {
 3321                                debug_panic!(
 3322                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3323                                    rp.pattern,
 3324                                    path.display(),
 3325                                    e
 3326                                );
 3327                                rp.pattern.clone()
 3328                            });
 3329                        base_uri.push(path);
 3330                        (base_uri, pattern)
 3331                    }
 3332                };
 3333
 3334                if let Some(glob) = Glob::new(&pattern).log_err() {
 3335                    if !path
 3336                        .components()
 3337                        .any(|c| matches!(c, path::Component::Normal(_)))
 3338                    {
 3339                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3340                        // rather than adding a new watcher for `/`.
 3341                        for worktree in &worktrees {
 3342                            worktree_globs
 3343                                .entry(worktree.read(cx).id())
 3344                                .or_insert_with(GlobSetBuilder::new)
 3345                                .add(glob.clone());
 3346                        }
 3347                    } else {
 3348                        abs_globs
 3349                            .entry(path.into())
 3350                            .or_insert_with(GlobSetBuilder::new)
 3351                            .add(glob);
 3352                    }
 3353                }
 3354            }
 3355        }
 3356
 3357        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3358        for (worktree_id, builder) in worktree_globs {
 3359            if let Ok(globset) = builder.build() {
 3360                watch_builder.watch_worktree(worktree_id, globset);
 3361            }
 3362        }
 3363        for (abs_path, builder) in abs_globs {
 3364            if let Ok(globset) = builder.build() {
 3365                watch_builder.watch_abs_path(abs_path, globset);
 3366            }
 3367        }
 3368        watch_builder
 3369    }
 3370
 3371    fn worktree_and_path_for_file_watcher(
 3372        worktrees: &[Entity<Worktree>],
 3373        watcher: &FileSystemWatcher,
 3374        cx: &App,
 3375    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3376        worktrees.iter().find_map(|worktree| {
 3377            let tree = worktree.read(cx);
 3378            let worktree_root_path = tree.abs_path();
 3379            let path_style = tree.path_style();
 3380            match &watcher.glob_pattern {
 3381                lsp::GlobPattern::String(s) => {
 3382                    let watcher_path = SanitizedPath::new(s);
 3383                    let relative = watcher_path
 3384                        .as_path()
 3385                        .strip_prefix(&worktree_root_path)
 3386                        .ok()?;
 3387                    let literal_prefix = glob_literal_prefix(relative);
 3388                    Some((
 3389                        worktree.clone(),
 3390                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3391                        relative.to_string_lossy().into_owned(),
 3392                    ))
 3393                }
 3394                lsp::GlobPattern::Relative(rp) => {
 3395                    let base_uri = match &rp.base_uri {
 3396                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3397                        lsp::OneOf::Right(base_uri) => base_uri,
 3398                    }
 3399                    .to_file_path()
 3400                    .ok()?;
 3401                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3402                    let mut literal_prefix = relative.to_owned();
 3403                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3404                    Some((
 3405                        worktree.clone(),
 3406                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3407                        rp.pattern.clone(),
 3408                    ))
 3409                }
 3410            }
 3411        })
 3412    }
 3413
 3414    fn rebuild_watched_paths(
 3415        &mut self,
 3416        language_server_id: LanguageServerId,
 3417        cx: &mut Context<LspStore>,
 3418    ) {
 3419        let Some(registrations) = self
 3420            .language_server_dynamic_registrations
 3421            .get(&language_server_id)
 3422        else {
 3423            return;
 3424        };
 3425
 3426        let watch_builder = self.rebuild_watched_paths_inner(
 3427            language_server_id,
 3428            registrations.did_change_watched_files.values().flatten(),
 3429            cx,
 3430        );
 3431        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3432        self.language_server_watched_paths
 3433            .insert(language_server_id, watcher);
 3434
 3435        cx.notify();
 3436    }
 3437
 3438    fn on_lsp_did_change_watched_files(
 3439        &mut self,
 3440        language_server_id: LanguageServerId,
 3441        registration_id: &str,
 3442        params: DidChangeWatchedFilesRegistrationOptions,
 3443        cx: &mut Context<LspStore>,
 3444    ) {
 3445        let registrations = self
 3446            .language_server_dynamic_registrations
 3447            .entry(language_server_id)
 3448            .or_default();
 3449
 3450        registrations
 3451            .did_change_watched_files
 3452            .insert(registration_id.to_string(), params.watchers);
 3453
 3454        self.rebuild_watched_paths(language_server_id, cx);
 3455    }
 3456
 3457    fn on_lsp_unregister_did_change_watched_files(
 3458        &mut self,
 3459        language_server_id: LanguageServerId,
 3460        registration_id: &str,
 3461        cx: &mut Context<LspStore>,
 3462    ) {
 3463        let registrations = self
 3464            .language_server_dynamic_registrations
 3465            .entry(language_server_id)
 3466            .or_default();
 3467
 3468        if registrations
 3469            .did_change_watched_files
 3470            .remove(registration_id)
 3471            .is_some()
 3472        {
 3473            log::info!(
 3474                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3475                language_server_id,
 3476                registration_id
 3477            );
 3478        } else {
 3479            log::warn!(
 3480                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3481                language_server_id,
 3482                registration_id
 3483            );
 3484        }
 3485
 3486        self.rebuild_watched_paths(language_server_id, cx);
 3487    }
 3488
 3489    async fn initialization_options_for_adapter(
 3490        adapter: Arc<dyn LspAdapter>,
 3491        delegate: &Arc<dyn LspAdapterDelegate>,
 3492    ) -> Result<Option<serde_json::Value>> {
 3493        let Some(mut initialization_config) =
 3494            adapter.clone().initialization_options(delegate).await?
 3495        else {
 3496            return Ok(None);
 3497        };
 3498
 3499        for other_adapter in delegate.registered_lsp_adapters() {
 3500            if other_adapter.name() == adapter.name() {
 3501                continue;
 3502            }
 3503            if let Ok(Some(target_config)) = other_adapter
 3504                .clone()
 3505                .additional_initialization_options(adapter.name(), delegate)
 3506                .await
 3507            {
 3508                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3509            }
 3510        }
 3511
 3512        Ok(Some(initialization_config))
 3513    }
 3514
 3515    async fn workspace_configuration_for_adapter(
 3516        adapter: Arc<dyn LspAdapter>,
 3517        delegate: &Arc<dyn LspAdapterDelegate>,
 3518        toolchain: Option<Toolchain>,
 3519        cx: &mut AsyncApp,
 3520    ) -> Result<serde_json::Value> {
 3521        let mut workspace_config = adapter
 3522            .clone()
 3523            .workspace_configuration(delegate, toolchain, cx)
 3524            .await?;
 3525
 3526        for other_adapter in delegate.registered_lsp_adapters() {
 3527            if other_adapter.name() == adapter.name() {
 3528                continue;
 3529            }
 3530            if let Ok(Some(target_config)) = other_adapter
 3531                .clone()
 3532                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3533                .await
 3534            {
 3535                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3536            }
 3537        }
 3538
 3539        Ok(workspace_config)
 3540    }
 3541
 3542    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3543        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3544            Some(server.clone())
 3545        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3546            Some(Arc::clone(server))
 3547        } else {
 3548            None
 3549        }
 3550    }
 3551}
 3552
 3553fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3554    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3555        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3556            language_server_id: server.server_id(),
 3557            name: Some(server.name()),
 3558            message: proto::update_language_server::Variant::MetadataUpdated(
 3559                proto::ServerMetadataUpdated {
 3560                    capabilities: Some(capabilities),
 3561                    binary: Some(proto::LanguageServerBinaryInfo {
 3562                        path: server.binary().path.to_string_lossy().into_owned(),
 3563                        arguments: server
 3564                            .binary()
 3565                            .arguments
 3566                            .iter()
 3567                            .map(|arg| arg.to_string_lossy().into_owned())
 3568                            .collect(),
 3569                    }),
 3570                    configuration: serde_json::to_string(server.configuration()).ok(),
 3571                    workspace_folders: server
 3572                        .workspace_folders()
 3573                        .iter()
 3574                        .map(|uri| uri.to_string())
 3575                        .collect(),
 3576                },
 3577            ),
 3578        });
 3579    }
 3580}
 3581
 3582#[derive(Debug)]
 3583pub struct FormattableBuffer {
 3584    handle: Entity<Buffer>,
 3585    abs_path: Option<PathBuf>,
 3586    env: Option<HashMap<String, String>>,
 3587    ranges: Option<Vec<Range<Anchor>>>,
 3588}
 3589
 3590pub struct RemoteLspStore {
 3591    upstream_client: Option<AnyProtoClient>,
 3592    upstream_project_id: u64,
 3593}
 3594
 3595pub(crate) enum LspStoreMode {
 3596    Local(LocalLspStore),   // ssh host and collab host
 3597    Remote(RemoteLspStore), // collab guest
 3598}
 3599
 3600impl LspStoreMode {
 3601    fn is_local(&self) -> bool {
 3602        matches!(self, LspStoreMode::Local(_))
 3603    }
 3604}
 3605
 3606pub struct LspStore {
 3607    mode: LspStoreMode,
 3608    last_formatting_failure: Option<String>,
 3609    downstream_client: Option<(AnyProtoClient, u64)>,
 3610    nonce: u128,
 3611    buffer_store: Entity<BufferStore>,
 3612    worktree_store: Entity<WorktreeStore>,
 3613    pub languages: Arc<LanguageRegistry>,
 3614    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3615    active_entry: Option<ProjectEntryId>,
 3616    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3617    _maintain_buffer_languages: Task<()>,
 3618    diagnostic_summaries:
 3619        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3620    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3621    lsp_data: HashMap<BufferId, BufferLspData>,
 3622    next_hint_id: Arc<AtomicUsize>,
 3623}
 3624
 3625#[derive(Debug)]
 3626pub struct BufferLspData {
 3627    buffer_version: Global,
 3628    document_colors: Option<DocumentColorData>,
 3629    code_lens: Option<CodeLensData>,
 3630    inlay_hints: BufferInlayHints,
 3631    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3632    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3633}
 3634
 3635#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3636struct LspKey {
 3637    request_type: TypeId,
 3638    server_queried: Option<LanguageServerId>,
 3639}
 3640
 3641impl BufferLspData {
 3642    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3643        Self {
 3644            buffer_version: buffer.read(cx).version(),
 3645            document_colors: None,
 3646            code_lens: None,
 3647            inlay_hints: BufferInlayHints::new(buffer, cx),
 3648            lsp_requests: HashMap::default(),
 3649            chunk_lsp_requests: HashMap::default(),
 3650        }
 3651    }
 3652
 3653    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3654        if let Some(document_colors) = &mut self.document_colors {
 3655            document_colors.colors.remove(&for_server);
 3656            document_colors.cache_version += 1;
 3657        }
 3658
 3659        if let Some(code_lens) = &mut self.code_lens {
 3660            code_lens.lens.remove(&for_server);
 3661        }
 3662
 3663        self.inlay_hints.remove_server_data(for_server);
 3664    }
 3665
 3666    #[cfg(any(test, feature = "test-support"))]
 3667    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3668        &self.inlay_hints
 3669    }
 3670}
 3671
 3672#[derive(Debug, Default, Clone)]
 3673pub struct DocumentColors {
 3674    pub colors: HashSet<DocumentColor>,
 3675    pub cache_version: Option<usize>,
 3676}
 3677
 3678type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3679type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3680
 3681#[derive(Debug, Default)]
 3682struct DocumentColorData {
 3683    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3684    cache_version: usize,
 3685    colors_update: Option<(Global, DocumentColorTask)>,
 3686}
 3687
 3688#[derive(Debug, Default)]
 3689struct CodeLensData {
 3690    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3691    update: Option<(Global, CodeLensTask)>,
 3692}
 3693
 3694#[derive(Debug)]
 3695pub enum LspStoreEvent {
 3696    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3697    LanguageServerRemoved(LanguageServerId),
 3698    LanguageServerUpdate {
 3699        language_server_id: LanguageServerId,
 3700        name: Option<LanguageServerName>,
 3701        message: proto::update_language_server::Variant,
 3702    },
 3703    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3704    LanguageServerPrompt(LanguageServerPromptRequest),
 3705    LanguageDetected {
 3706        buffer: Entity<Buffer>,
 3707        new_language: Option<Arc<Language>>,
 3708    },
 3709    Notification(String),
 3710    RefreshInlayHints {
 3711        server_id: LanguageServerId,
 3712        request_id: Option<usize>,
 3713    },
 3714    RefreshCodeLens,
 3715    DiagnosticsUpdated {
 3716        server_id: LanguageServerId,
 3717        paths: Vec<ProjectPath>,
 3718    },
 3719    DiskBasedDiagnosticsStarted {
 3720        language_server_id: LanguageServerId,
 3721    },
 3722    DiskBasedDiagnosticsFinished {
 3723        language_server_id: LanguageServerId,
 3724    },
 3725    SnippetEdit {
 3726        buffer_id: BufferId,
 3727        edits: Vec<(lsp::Range, Snippet)>,
 3728        most_recent_edit: clock::Lamport,
 3729    },
 3730}
 3731
 3732#[derive(Clone, Debug, Serialize)]
 3733pub struct LanguageServerBinaryInfo {
 3734    pub path: String,
 3735    pub arguments: Vec<String>,
 3736    pub env: Option<HashMap<String, String>>,
 3737}
 3738
 3739#[derive(Clone, Debug, Serialize)]
 3740pub struct LanguageServerStatus {
 3741    pub name: LanguageServerName,
 3742    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3743    pub has_pending_diagnostic_updates: bool,
 3744    pub progress_tokens: HashSet<ProgressToken>,
 3745    pub worktree: Option<WorktreeId>,
 3746    pub binary: Option<LanguageServerBinaryInfo>,
 3747    pub configuration: Option<Value>,
 3748    pub workspace_folders: BTreeSet<Uri>,
 3749}
 3750
 3751#[derive(Clone, Debug)]
 3752struct CoreSymbol {
 3753    pub language_server_name: LanguageServerName,
 3754    pub source_worktree_id: WorktreeId,
 3755    pub source_language_server_id: LanguageServerId,
 3756    pub path: SymbolLocation,
 3757    pub name: String,
 3758    pub kind: lsp::SymbolKind,
 3759    pub range: Range<Unclipped<PointUtf16>>,
 3760}
 3761
 3762#[derive(Clone, Debug, PartialEq, Eq)]
 3763pub enum SymbolLocation {
 3764    InProject(ProjectPath),
 3765    OutsideProject {
 3766        abs_path: Arc<Path>,
 3767        signature: [u8; 32],
 3768    },
 3769}
 3770
 3771impl SymbolLocation {
 3772    fn file_name(&self) -> Option<&str> {
 3773        match self {
 3774            Self::InProject(path) => path.path.file_name(),
 3775            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3776        }
 3777    }
 3778}
 3779
 3780impl LspStore {
 3781    pub fn init(client: &AnyProtoClient) {
 3782        client.add_entity_request_handler(Self::handle_lsp_query);
 3783        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3784        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3785        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3786        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3787        client.add_entity_message_handler(Self::handle_start_language_server);
 3788        client.add_entity_message_handler(Self::handle_update_language_server);
 3789        client.add_entity_message_handler(Self::handle_language_server_log);
 3790        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3791        client.add_entity_request_handler(Self::handle_format_buffers);
 3792        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3793        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3794        client.add_entity_request_handler(Self::handle_apply_code_action);
 3795        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3796        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3797        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3798        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3799        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3800        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3801        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3802        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3803        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3804        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3805        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3806        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3807        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3808        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3809        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3810        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3811        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3812
 3813        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3814        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3815        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3816        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3817        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3818        client.add_entity_request_handler(
 3819            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3820        );
 3821        client.add_entity_request_handler(
 3822            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3823        );
 3824        client.add_entity_request_handler(
 3825            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3826        );
 3827    }
 3828
 3829    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3830        match &self.mode {
 3831            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3832            _ => None,
 3833        }
 3834    }
 3835
 3836    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3837        match &self.mode {
 3838            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3839            _ => None,
 3840        }
 3841    }
 3842
 3843    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3844        match &mut self.mode {
 3845            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3846            _ => None,
 3847        }
 3848    }
 3849
 3850    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3851        match &self.mode {
 3852            LspStoreMode::Remote(RemoteLspStore {
 3853                upstream_client: Some(upstream_client),
 3854                upstream_project_id,
 3855                ..
 3856            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3857
 3858            LspStoreMode::Remote(RemoteLspStore {
 3859                upstream_client: None,
 3860                ..
 3861            }) => None,
 3862            LspStoreMode::Local(_) => None,
 3863        }
 3864    }
 3865
 3866    pub fn new_local(
 3867        buffer_store: Entity<BufferStore>,
 3868        worktree_store: Entity<WorktreeStore>,
 3869        prettier_store: Entity<PrettierStore>,
 3870        toolchain_store: Entity<LocalToolchainStore>,
 3871        environment: Entity<ProjectEnvironment>,
 3872        manifest_tree: Entity<ManifestTree>,
 3873        languages: Arc<LanguageRegistry>,
 3874        http_client: Arc<dyn HttpClient>,
 3875        fs: Arc<dyn Fs>,
 3876        cx: &mut Context<Self>,
 3877    ) -> Self {
 3878        let yarn = YarnPathStore::new(fs.clone(), cx);
 3879        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3880            .detach();
 3881        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3882            .detach();
 3883        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3884            .detach();
 3885        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3886            .detach();
 3887        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3888            .detach();
 3889        subscribe_to_binary_statuses(&languages, cx).detach();
 3890
 3891        let _maintain_workspace_config = {
 3892            let (sender, receiver) = watch::channel();
 3893            (Self::maintain_workspace_config(receiver, cx), sender)
 3894        };
 3895
 3896        Self {
 3897            mode: LspStoreMode::Local(LocalLspStore {
 3898                weak: cx.weak_entity(),
 3899                worktree_store: worktree_store.clone(),
 3900
 3901                supplementary_language_servers: Default::default(),
 3902                languages: languages.clone(),
 3903                language_server_ids: Default::default(),
 3904                language_servers: Default::default(),
 3905                last_workspace_edits_by_language_server: Default::default(),
 3906                language_server_watched_paths: Default::default(),
 3907                language_server_paths_watched_for_rename: Default::default(),
 3908                language_server_dynamic_registrations: Default::default(),
 3909                buffers_being_formatted: Default::default(),
 3910                buffer_snapshots: Default::default(),
 3911                prettier_store,
 3912                environment,
 3913                http_client,
 3914                fs,
 3915                yarn,
 3916                next_diagnostic_group_id: Default::default(),
 3917                diagnostics: Default::default(),
 3918                _subscription: cx.on_app_quit(|this, cx| {
 3919                    this.as_local_mut()
 3920                        .unwrap()
 3921                        .shutdown_language_servers_on_quit(cx)
 3922                }),
 3923                lsp_tree: LanguageServerTree::new(
 3924                    manifest_tree,
 3925                    languages.clone(),
 3926                    toolchain_store.clone(),
 3927                ),
 3928                toolchain_store,
 3929                registered_buffers: HashMap::default(),
 3930                buffers_opened_in_servers: HashMap::default(),
 3931                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3932                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3933                    .manifest_file_names(),
 3934            }),
 3935            last_formatting_failure: None,
 3936            downstream_client: None,
 3937            buffer_store,
 3938            worktree_store,
 3939            languages: languages.clone(),
 3940            language_server_statuses: Default::default(),
 3941            nonce: StdRng::from_os_rng().random(),
 3942            diagnostic_summaries: HashMap::default(),
 3943            lsp_server_capabilities: HashMap::default(),
 3944            lsp_data: HashMap::default(),
 3945            next_hint_id: Arc::default(),
 3946            active_entry: None,
 3947            _maintain_workspace_config,
 3948            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3949        }
 3950    }
 3951
 3952    fn send_lsp_proto_request<R: LspCommand>(
 3953        &self,
 3954        buffer: Entity<Buffer>,
 3955        client: AnyProtoClient,
 3956        upstream_project_id: u64,
 3957        request: R,
 3958        cx: &mut Context<LspStore>,
 3959    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3960        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3961            return Task::ready(Ok(R::Response::default()));
 3962        }
 3963        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3964        cx.spawn(async move |this, cx| {
 3965            let response = client.request(message).await?;
 3966            let this = this.upgrade().context("project dropped")?;
 3967            request
 3968                .response_from_proto(response, this, buffer, cx.clone())
 3969                .await
 3970        })
 3971    }
 3972
 3973    pub(super) fn new_remote(
 3974        buffer_store: Entity<BufferStore>,
 3975        worktree_store: Entity<WorktreeStore>,
 3976        languages: Arc<LanguageRegistry>,
 3977        upstream_client: AnyProtoClient,
 3978        project_id: u64,
 3979        cx: &mut Context<Self>,
 3980    ) -> Self {
 3981        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3982            .detach();
 3983        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3984            .detach();
 3985        subscribe_to_binary_statuses(&languages, cx).detach();
 3986        let _maintain_workspace_config = {
 3987            let (sender, receiver) = watch::channel();
 3988            (Self::maintain_workspace_config(receiver, cx), sender)
 3989        };
 3990        Self {
 3991            mode: LspStoreMode::Remote(RemoteLspStore {
 3992                upstream_client: Some(upstream_client),
 3993                upstream_project_id: project_id,
 3994            }),
 3995            downstream_client: None,
 3996            last_formatting_failure: None,
 3997            buffer_store,
 3998            worktree_store,
 3999            languages: languages.clone(),
 4000            language_server_statuses: Default::default(),
 4001            nonce: StdRng::from_os_rng().random(),
 4002            diagnostic_summaries: HashMap::default(),
 4003            lsp_server_capabilities: HashMap::default(),
 4004            next_hint_id: Arc::default(),
 4005            lsp_data: HashMap::default(),
 4006            active_entry: None,
 4007
 4008            _maintain_workspace_config,
 4009            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4010        }
 4011    }
 4012
 4013    fn on_buffer_store_event(
 4014        &mut self,
 4015        _: Entity<BufferStore>,
 4016        event: &BufferStoreEvent,
 4017        cx: &mut Context<Self>,
 4018    ) {
 4019        match event {
 4020            BufferStoreEvent::BufferAdded(buffer) => {
 4021                self.on_buffer_added(buffer, cx).log_err();
 4022            }
 4023            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4024                let buffer_id = buffer.read(cx).remote_id();
 4025                if let Some(local) = self.as_local_mut()
 4026                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4027                {
 4028                    local.reset_buffer(buffer, old_file, cx);
 4029
 4030                    if local.registered_buffers.contains_key(&buffer_id) {
 4031                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4032                    }
 4033                }
 4034
 4035                self.detect_language_for_buffer(buffer, cx);
 4036                if let Some(local) = self.as_local_mut() {
 4037                    local.initialize_buffer(buffer, cx);
 4038                    if local.registered_buffers.contains_key(&buffer_id) {
 4039                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4040                    }
 4041                }
 4042            }
 4043            _ => {}
 4044        }
 4045    }
 4046
 4047    fn on_worktree_store_event(
 4048        &mut self,
 4049        _: Entity<WorktreeStore>,
 4050        event: &WorktreeStoreEvent,
 4051        cx: &mut Context<Self>,
 4052    ) {
 4053        match event {
 4054            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4055                if !worktree.read(cx).is_local() {
 4056                    return;
 4057                }
 4058                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4059                    worktree::Event::UpdatedEntries(changes) => {
 4060                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4061                    }
 4062                    worktree::Event::UpdatedGitRepositories(_)
 4063                    | worktree::Event::DeletedEntry(_) => {}
 4064                })
 4065                .detach()
 4066            }
 4067            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4068            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4069                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4070            }
 4071            WorktreeStoreEvent::WorktreeReleased(..)
 4072            | WorktreeStoreEvent::WorktreeOrderChanged
 4073            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4074            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4075            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4076        }
 4077    }
 4078
 4079    fn on_prettier_store_event(
 4080        &mut self,
 4081        _: Entity<PrettierStore>,
 4082        event: &PrettierStoreEvent,
 4083        cx: &mut Context<Self>,
 4084    ) {
 4085        match event {
 4086            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4087                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4088            }
 4089            PrettierStoreEvent::LanguageServerAdded {
 4090                new_server_id,
 4091                name,
 4092                prettier_server,
 4093            } => {
 4094                self.register_supplementary_language_server(
 4095                    *new_server_id,
 4096                    name.clone(),
 4097                    prettier_server.clone(),
 4098                    cx,
 4099                );
 4100            }
 4101        }
 4102    }
 4103
 4104    fn on_toolchain_store_event(
 4105        &mut self,
 4106        _: Entity<LocalToolchainStore>,
 4107        event: &ToolchainStoreEvent,
 4108        _: &mut Context<Self>,
 4109    ) {
 4110        if let ToolchainStoreEvent::ToolchainActivated = event {
 4111            self.request_workspace_config_refresh()
 4112        }
 4113    }
 4114
 4115    fn request_workspace_config_refresh(&mut self) {
 4116        *self._maintain_workspace_config.1.borrow_mut() = ();
 4117    }
 4118
 4119    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4120        self.as_local().map(|local| local.prettier_store.clone())
 4121    }
 4122
 4123    fn on_buffer_event(
 4124        &mut self,
 4125        buffer: Entity<Buffer>,
 4126        event: &language::BufferEvent,
 4127        cx: &mut Context<Self>,
 4128    ) {
 4129        match event {
 4130            language::BufferEvent::Edited => {
 4131                self.on_buffer_edited(buffer, cx);
 4132            }
 4133
 4134            language::BufferEvent::Saved => {
 4135                self.on_buffer_saved(buffer, cx);
 4136            }
 4137
 4138            _ => {}
 4139        }
 4140    }
 4141
 4142    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4143        buffer
 4144            .read(cx)
 4145            .set_language_registry(self.languages.clone());
 4146
 4147        cx.subscribe(buffer, |this, buffer, event, cx| {
 4148            this.on_buffer_event(buffer, event, cx);
 4149        })
 4150        .detach();
 4151
 4152        self.detect_language_for_buffer(buffer, cx);
 4153        if let Some(local) = self.as_local_mut() {
 4154            local.initialize_buffer(buffer, cx);
 4155        }
 4156
 4157        Ok(())
 4158    }
 4159
 4160    pub(crate) fn register_buffer_with_language_servers(
 4161        &mut self,
 4162        buffer: &Entity<Buffer>,
 4163        only_register_servers: HashSet<LanguageServerSelector>,
 4164        ignore_refcounts: bool,
 4165        cx: &mut Context<Self>,
 4166    ) -> OpenLspBufferHandle {
 4167        let buffer_id = buffer.read(cx).remote_id();
 4168        let handle = cx.new(|_| buffer.clone());
 4169        if let Some(local) = self.as_local_mut() {
 4170            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4171            if !ignore_refcounts {
 4172                *refcount += 1;
 4173            }
 4174
 4175            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4176            // 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
 4177            // 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
 4178            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4179            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4180                return handle;
 4181            };
 4182            if !file.is_local() {
 4183                return handle;
 4184            }
 4185
 4186            if ignore_refcounts || *refcount == 1 {
 4187                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4188            }
 4189            if !ignore_refcounts {
 4190                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4191                    let refcount = {
 4192                        let local = lsp_store.as_local_mut().unwrap();
 4193                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4194                            debug_panic!("bad refcounting");
 4195                            return;
 4196                        };
 4197
 4198                        *refcount -= 1;
 4199                        *refcount
 4200                    };
 4201                    if refcount == 0 {
 4202                        lsp_store.lsp_data.remove(&buffer_id);
 4203                        let local = lsp_store.as_local_mut().unwrap();
 4204                        local.registered_buffers.remove(&buffer_id);
 4205                        local.buffers_opened_in_servers.remove(&buffer_id);
 4206                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4207                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4208                        }
 4209                    }
 4210                })
 4211                .detach();
 4212            }
 4213        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4214            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4215            cx.background_spawn(async move {
 4216                upstream_client
 4217                    .request(proto::RegisterBufferWithLanguageServers {
 4218                        project_id: upstream_project_id,
 4219                        buffer_id,
 4220                        only_servers: only_register_servers
 4221                            .into_iter()
 4222                            .map(|selector| {
 4223                                let selector = match selector {
 4224                                    LanguageServerSelector::Id(language_server_id) => {
 4225                                        proto::language_server_selector::Selector::ServerId(
 4226                                            language_server_id.to_proto(),
 4227                                        )
 4228                                    }
 4229                                    LanguageServerSelector::Name(language_server_name) => {
 4230                                        proto::language_server_selector::Selector::Name(
 4231                                            language_server_name.to_string(),
 4232                                        )
 4233                                    }
 4234                                };
 4235                                proto::LanguageServerSelector {
 4236                                    selector: Some(selector),
 4237                                }
 4238                            })
 4239                            .collect(),
 4240                    })
 4241                    .await
 4242            })
 4243            .detach();
 4244        } else {
 4245            // Our remote connection got closed
 4246        }
 4247        handle
 4248    }
 4249
 4250    fn maintain_buffer_languages(
 4251        languages: Arc<LanguageRegistry>,
 4252        cx: &mut Context<Self>,
 4253    ) -> Task<()> {
 4254        let mut subscription = languages.subscribe();
 4255        let mut prev_reload_count = languages.reload_count();
 4256        cx.spawn(async move |this, cx| {
 4257            while let Some(()) = subscription.next().await {
 4258                if let Some(this) = this.upgrade() {
 4259                    // If the language registry has been reloaded, then remove and
 4260                    // re-assign the languages on all open buffers.
 4261                    let reload_count = languages.reload_count();
 4262                    if reload_count > prev_reload_count {
 4263                        prev_reload_count = reload_count;
 4264                        this.update(cx, |this, cx| {
 4265                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4266                                for buffer in buffer_store.buffers() {
 4267                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4268                                    {
 4269                                        buffer
 4270                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4271                                        if let Some(local) = this.as_local_mut() {
 4272                                            local.reset_buffer(&buffer, &f, cx);
 4273
 4274                                            if local
 4275                                                .registered_buffers
 4276                                                .contains_key(&buffer.read(cx).remote_id())
 4277                                                && let Some(file_url) =
 4278                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4279                                            {
 4280                                                local.unregister_buffer_from_language_servers(
 4281                                                    &buffer, &file_url, cx,
 4282                                                );
 4283                                            }
 4284                                        }
 4285                                    }
 4286                                }
 4287                            });
 4288                        })
 4289                        .ok();
 4290                    }
 4291
 4292                    this.update(cx, |this, cx| {
 4293                        let mut plain_text_buffers = Vec::new();
 4294                        let mut buffers_with_unknown_injections = Vec::new();
 4295                        for handle in this.buffer_store.read(cx).buffers() {
 4296                            let buffer = handle.read(cx);
 4297                            if buffer.language().is_none()
 4298                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4299                            {
 4300                                plain_text_buffers.push(handle);
 4301                            } else if buffer.contains_unknown_injections() {
 4302                                buffers_with_unknown_injections.push(handle);
 4303                            }
 4304                        }
 4305
 4306                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4307                        // and reused later in the invisible worktrees.
 4308                        plain_text_buffers.sort_by_key(|buffer| {
 4309                            Reverse(
 4310                                File::from_dyn(buffer.read(cx).file())
 4311                                    .map(|file| file.worktree.read(cx).is_visible()),
 4312                            )
 4313                        });
 4314
 4315                        for buffer in plain_text_buffers {
 4316                            this.detect_language_for_buffer(&buffer, cx);
 4317                            if let Some(local) = this.as_local_mut() {
 4318                                local.initialize_buffer(&buffer, cx);
 4319                                if local
 4320                                    .registered_buffers
 4321                                    .contains_key(&buffer.read(cx).remote_id())
 4322                                {
 4323                                    local.register_buffer_with_language_servers(
 4324                                        &buffer,
 4325                                        HashSet::default(),
 4326                                        cx,
 4327                                    );
 4328                                }
 4329                            }
 4330                        }
 4331
 4332                        for buffer in buffers_with_unknown_injections {
 4333                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4334                        }
 4335                    })
 4336                    .ok();
 4337                }
 4338            }
 4339        })
 4340    }
 4341
 4342    fn detect_language_for_buffer(
 4343        &mut self,
 4344        buffer_handle: &Entity<Buffer>,
 4345        cx: &mut Context<Self>,
 4346    ) -> Option<language::AvailableLanguage> {
 4347        // If the buffer has a language, set it and start the language server if we haven't already.
 4348        let buffer = buffer_handle.read(cx);
 4349        let file = buffer.file()?;
 4350
 4351        let content = buffer.as_rope();
 4352        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4353        if let Some(available_language) = &available_language {
 4354            if let Some(Ok(Ok(new_language))) = self
 4355                .languages
 4356                .load_language(available_language)
 4357                .now_or_never()
 4358            {
 4359                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4360            }
 4361        } else {
 4362            cx.emit(LspStoreEvent::LanguageDetected {
 4363                buffer: buffer_handle.clone(),
 4364                new_language: None,
 4365            });
 4366        }
 4367
 4368        available_language
 4369    }
 4370
 4371    pub(crate) fn set_language_for_buffer(
 4372        &mut self,
 4373        buffer_entity: &Entity<Buffer>,
 4374        new_language: Arc<Language>,
 4375        cx: &mut Context<Self>,
 4376    ) {
 4377        let buffer = buffer_entity.read(cx);
 4378        let buffer_file = buffer.file().cloned();
 4379        let buffer_id = buffer.remote_id();
 4380        if let Some(local_store) = self.as_local_mut()
 4381            && local_store.registered_buffers.contains_key(&buffer_id)
 4382            && let Some(abs_path) =
 4383                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4384            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4385        {
 4386            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4387        }
 4388        buffer_entity.update(cx, |buffer, cx| {
 4389            if buffer
 4390                .language()
 4391                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4392            {
 4393                buffer.set_language(Some(new_language.clone()), cx);
 4394            }
 4395        });
 4396
 4397        let settings =
 4398            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4399        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4400
 4401        let worktree_id = if let Some(file) = buffer_file {
 4402            let worktree = file.worktree.clone();
 4403
 4404            if let Some(local) = self.as_local_mut()
 4405                && local.registered_buffers.contains_key(&buffer_id)
 4406            {
 4407                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4408            }
 4409            Some(worktree.read(cx).id())
 4410        } else {
 4411            None
 4412        };
 4413
 4414        if settings.prettier.allowed
 4415            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4416        {
 4417            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4418            if let Some(prettier_store) = prettier_store {
 4419                prettier_store.update(cx, |prettier_store, cx| {
 4420                    prettier_store.install_default_prettier(
 4421                        worktree_id,
 4422                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4423                        cx,
 4424                    )
 4425                })
 4426            }
 4427        }
 4428
 4429        cx.emit(LspStoreEvent::LanguageDetected {
 4430            buffer: buffer_entity.clone(),
 4431            new_language: Some(new_language),
 4432        })
 4433    }
 4434
 4435    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4436        self.buffer_store.clone()
 4437    }
 4438
 4439    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4440        self.active_entry = active_entry;
 4441    }
 4442
 4443    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4444        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4445            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4446        {
 4447            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4448                summaries
 4449                    .iter()
 4450                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4451            });
 4452            if let Some(summary) = summaries.next() {
 4453                client
 4454                    .send(proto::UpdateDiagnosticSummary {
 4455                        project_id: downstream_project_id,
 4456                        worktree_id: worktree.id().to_proto(),
 4457                        summary: Some(summary),
 4458                        more_summaries: summaries.collect(),
 4459                    })
 4460                    .log_err();
 4461            }
 4462        }
 4463    }
 4464
 4465    fn is_capable_for_proto_request<R>(
 4466        &self,
 4467        buffer: &Entity<Buffer>,
 4468        request: &R,
 4469        cx: &App,
 4470    ) -> bool
 4471    where
 4472        R: LspCommand,
 4473    {
 4474        self.check_if_capable_for_proto_request(
 4475            buffer,
 4476            |capabilities| {
 4477                request.check_capabilities(AdapterServerCapabilities {
 4478                    server_capabilities: capabilities.clone(),
 4479                    code_action_kinds: None,
 4480                })
 4481            },
 4482            cx,
 4483        )
 4484    }
 4485
 4486    fn check_if_capable_for_proto_request<F>(
 4487        &self,
 4488        buffer: &Entity<Buffer>,
 4489        check: F,
 4490        cx: &App,
 4491    ) -> bool
 4492    where
 4493        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4494    {
 4495        let Some(language) = buffer.read(cx).language().cloned() else {
 4496            return false;
 4497        };
 4498        let relevant_language_servers = self
 4499            .languages
 4500            .lsp_adapters(&language.name())
 4501            .into_iter()
 4502            .map(|lsp_adapter| lsp_adapter.name())
 4503            .collect::<HashSet<_>>();
 4504        self.language_server_statuses
 4505            .iter()
 4506            .filter_map(|(server_id, server_status)| {
 4507                relevant_language_servers
 4508                    .contains(&server_status.name)
 4509                    .then_some(server_id)
 4510            })
 4511            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4512            .any(check)
 4513    }
 4514
 4515    fn all_capable_for_proto_request<F>(
 4516        &self,
 4517        buffer: &Entity<Buffer>,
 4518        mut check: F,
 4519        cx: &App,
 4520    ) -> Vec<lsp::LanguageServerId>
 4521    where
 4522        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4523    {
 4524        let Some(language) = buffer.read(cx).language().cloned() else {
 4525            return Vec::default();
 4526        };
 4527        let relevant_language_servers = self
 4528            .languages
 4529            .lsp_adapters(&language.name())
 4530            .into_iter()
 4531            .map(|lsp_adapter| lsp_adapter.name())
 4532            .collect::<HashSet<_>>();
 4533        self.language_server_statuses
 4534            .iter()
 4535            .filter_map(|(server_id, server_status)| {
 4536                relevant_language_servers
 4537                    .contains(&server_status.name)
 4538                    .then_some((server_id, &server_status.name))
 4539            })
 4540            .filter_map(|(server_id, server_name)| {
 4541                self.lsp_server_capabilities
 4542                    .get(server_id)
 4543                    .map(|c| (server_id, server_name, c))
 4544            })
 4545            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4546            .map(|(server_id, _, _)| *server_id)
 4547            .collect()
 4548    }
 4549
 4550    pub fn request_lsp<R>(
 4551        &mut self,
 4552        buffer: Entity<Buffer>,
 4553        server: LanguageServerToQuery,
 4554        request: R,
 4555        cx: &mut Context<Self>,
 4556    ) -> Task<Result<R::Response>>
 4557    where
 4558        R: LspCommand,
 4559        <R::LspRequest as lsp::request::Request>::Result: Send,
 4560        <R::LspRequest as lsp::request::Request>::Params: Send,
 4561    {
 4562        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4563            return self.send_lsp_proto_request(
 4564                buffer,
 4565                upstream_client,
 4566                upstream_project_id,
 4567                request,
 4568                cx,
 4569            );
 4570        }
 4571
 4572        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4573            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4574                local
 4575                    .language_servers_for_buffer(buffer, cx)
 4576                    .find(|(_, server)| {
 4577                        request.check_capabilities(server.adapter_server_capabilities())
 4578                    })
 4579                    .map(|(_, server)| server.clone())
 4580            }),
 4581            LanguageServerToQuery::Other(id) => self
 4582                .language_server_for_local_buffer(buffer, id, cx)
 4583                .and_then(|(_, server)| {
 4584                    request
 4585                        .check_capabilities(server.adapter_server_capabilities())
 4586                        .then(|| Arc::clone(server))
 4587                }),
 4588        }) else {
 4589            return Task::ready(Ok(Default::default()));
 4590        };
 4591
 4592        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4593
 4594        let Some(file) = file else {
 4595            return Task::ready(Ok(Default::default()));
 4596        };
 4597
 4598        let lsp_params = match request.to_lsp_params_or_response(
 4599            &file.abs_path(cx),
 4600            buffer.read(cx),
 4601            &language_server,
 4602            cx,
 4603        ) {
 4604            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4605            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4606            Err(err) => {
 4607                let message = format!(
 4608                    "{} via {} failed: {}",
 4609                    request.display_name(),
 4610                    language_server.name(),
 4611                    err
 4612                );
 4613                // rust-analyzer likes to error with this when its still loading up
 4614                if !message.ends_with("content modified") {
 4615                    log::warn!("{message}");
 4616                }
 4617                return Task::ready(Err(anyhow!(message)));
 4618            }
 4619        };
 4620
 4621        let status = request.status();
 4622        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4623            return Task::ready(Ok(Default::default()));
 4624        }
 4625        cx.spawn(async move |this, cx| {
 4626            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4627
 4628            let id = lsp_request.id();
 4629            let _cleanup = if status.is_some() {
 4630                cx.update(|cx| {
 4631                    this.update(cx, |this, cx| {
 4632                        this.on_lsp_work_start(
 4633                            language_server.server_id(),
 4634                            ProgressToken::Number(id),
 4635                            LanguageServerProgress {
 4636                                is_disk_based_diagnostics_progress: false,
 4637                                is_cancellable: false,
 4638                                title: None,
 4639                                message: status.clone(),
 4640                                percentage: None,
 4641                                last_update_at: cx.background_executor().now(),
 4642                            },
 4643                            cx,
 4644                        );
 4645                    })
 4646                })
 4647                .log_err();
 4648
 4649                Some(defer(|| {
 4650                    cx.update(|cx| {
 4651                        this.update(cx, |this, cx| {
 4652                            this.on_lsp_work_end(
 4653                                language_server.server_id(),
 4654                                ProgressToken::Number(id),
 4655                                cx,
 4656                            );
 4657                        })
 4658                    })
 4659                    .log_err();
 4660                }))
 4661            } else {
 4662                None
 4663            };
 4664
 4665            let result = lsp_request.await.into_response();
 4666
 4667            let response = result.map_err(|err| {
 4668                let message = format!(
 4669                    "{} via {} failed: {}",
 4670                    request.display_name(),
 4671                    language_server.name(),
 4672                    err
 4673                );
 4674                // rust-analyzer likes to error with this when its still loading up
 4675                if !message.ends_with("content modified") {
 4676                    log::warn!("{message}");
 4677                }
 4678                anyhow::anyhow!(message)
 4679            })?;
 4680
 4681            request
 4682                .response_from_lsp(
 4683                    response,
 4684                    this.upgrade().context("no app context")?,
 4685                    buffer,
 4686                    language_server.server_id(),
 4687                    cx.clone(),
 4688                )
 4689                .await
 4690        })
 4691    }
 4692
 4693    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4694        let mut language_formatters_to_check = Vec::new();
 4695        for buffer in self.buffer_store.read(cx).buffers() {
 4696            let buffer = buffer.read(cx);
 4697            let buffer_file = File::from_dyn(buffer.file());
 4698            let buffer_language = buffer.language();
 4699            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4700            if buffer_language.is_some() {
 4701                language_formatters_to_check.push((
 4702                    buffer_file.map(|f| f.worktree_id(cx)),
 4703                    settings.into_owned(),
 4704                ));
 4705            }
 4706        }
 4707
 4708        self.request_workspace_config_refresh();
 4709
 4710        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4711            prettier_store.update(cx, |prettier_store, cx| {
 4712                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4713            })
 4714        }
 4715
 4716        cx.notify();
 4717    }
 4718
 4719    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4720        let buffer_store = self.buffer_store.clone();
 4721        let Some(local) = self.as_local_mut() else {
 4722            return;
 4723        };
 4724        let mut adapters = BTreeMap::default();
 4725        let get_adapter = {
 4726            let languages = local.languages.clone();
 4727            let environment = local.environment.clone();
 4728            let weak = local.weak.clone();
 4729            let worktree_store = local.worktree_store.clone();
 4730            let http_client = local.http_client.clone();
 4731            let fs = local.fs.clone();
 4732            move |worktree_id, cx: &mut App| {
 4733                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4734                Some(LocalLspAdapterDelegate::new(
 4735                    languages.clone(),
 4736                    &environment,
 4737                    weak.clone(),
 4738                    &worktree,
 4739                    http_client.clone(),
 4740                    fs.clone(),
 4741                    cx,
 4742                ))
 4743            }
 4744        };
 4745
 4746        let mut messages_to_report = Vec::new();
 4747        let (new_tree, to_stop) = {
 4748            let mut rebase = local.lsp_tree.rebase();
 4749            let buffers = buffer_store
 4750                .read(cx)
 4751                .buffers()
 4752                .filter_map(|buffer| {
 4753                    let raw_buffer = buffer.read(cx);
 4754                    if !local
 4755                        .registered_buffers
 4756                        .contains_key(&raw_buffer.remote_id())
 4757                    {
 4758                        return None;
 4759                    }
 4760                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4761                    let language = raw_buffer.language().cloned()?;
 4762                    Some((file, language, raw_buffer.remote_id()))
 4763                })
 4764                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4765            for (file, language, buffer_id) in buffers {
 4766                let worktree_id = file.worktree_id(cx);
 4767                let Some(worktree) = local
 4768                    .worktree_store
 4769                    .read(cx)
 4770                    .worktree_for_id(worktree_id, cx)
 4771                else {
 4772                    continue;
 4773                };
 4774
 4775                if let Some((_, apply)) = local.reuse_existing_language_server(
 4776                    rebase.server_tree(),
 4777                    &worktree,
 4778                    &language.name(),
 4779                    cx,
 4780                ) {
 4781                    (apply)(rebase.server_tree());
 4782                } else if let Some(lsp_delegate) = adapters
 4783                    .entry(worktree_id)
 4784                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4785                    .clone()
 4786                {
 4787                    let delegate =
 4788                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4789                    let path = file
 4790                        .path()
 4791                        .parent()
 4792                        .map(Arc::from)
 4793                        .unwrap_or_else(|| file.path().clone());
 4794                    let worktree_path = ProjectPath { worktree_id, path };
 4795                    let abs_path = file.abs_path(cx);
 4796                    let nodes = rebase
 4797                        .walk(
 4798                            worktree_path,
 4799                            language.name(),
 4800                            language.manifest(),
 4801                            delegate.clone(),
 4802                            cx,
 4803                        )
 4804                        .collect::<Vec<_>>();
 4805                    for node in nodes {
 4806                        let server_id = node.server_id_or_init(|disposition| {
 4807                            let path = &disposition.path;
 4808                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4809                            let key = LanguageServerSeed {
 4810                                worktree_id,
 4811                                name: disposition.server_name.clone(),
 4812                                settings: disposition.settings.clone(),
 4813                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4814                                    path.worktree_id,
 4815                                    &path.path,
 4816                                    language.name(),
 4817                                ),
 4818                            };
 4819                            local.language_server_ids.remove(&key);
 4820
 4821                            let server_id = local.get_or_insert_language_server(
 4822                                &worktree,
 4823                                lsp_delegate.clone(),
 4824                                disposition,
 4825                                &language.name(),
 4826                                cx,
 4827                            );
 4828                            if let Some(state) = local.language_servers.get(&server_id)
 4829                                && let Ok(uri) = uri
 4830                            {
 4831                                state.add_workspace_folder(uri);
 4832                            };
 4833                            server_id
 4834                        });
 4835
 4836                        if let Some(language_server_id) = server_id {
 4837                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4838                                language_server_id,
 4839                                name: node.name(),
 4840                                message:
 4841                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4842                                        proto::RegisteredForBuffer {
 4843                                            buffer_abs_path: abs_path
 4844                                                .to_string_lossy()
 4845                                                .into_owned(),
 4846                                            buffer_id: buffer_id.to_proto(),
 4847                                        },
 4848                                    ),
 4849                            });
 4850                        }
 4851                    }
 4852                } else {
 4853                    continue;
 4854                }
 4855            }
 4856            rebase.finish()
 4857        };
 4858        for message in messages_to_report {
 4859            cx.emit(message);
 4860        }
 4861        local.lsp_tree = new_tree;
 4862        for (id, _) in to_stop {
 4863            self.stop_local_language_server(id, cx).detach();
 4864        }
 4865    }
 4866
 4867    pub fn apply_code_action(
 4868        &self,
 4869        buffer_handle: Entity<Buffer>,
 4870        mut action: CodeAction,
 4871        push_to_history: bool,
 4872        cx: &mut Context<Self>,
 4873    ) -> Task<Result<ProjectTransaction>> {
 4874        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4875            let request = proto::ApplyCodeAction {
 4876                project_id,
 4877                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4878                action: Some(Self::serialize_code_action(&action)),
 4879            };
 4880            let buffer_store = self.buffer_store();
 4881            cx.spawn(async move |_, cx| {
 4882                let response = upstream_client
 4883                    .request(request)
 4884                    .await?
 4885                    .transaction
 4886                    .context("missing transaction")?;
 4887
 4888                buffer_store
 4889                    .update(cx, |buffer_store, cx| {
 4890                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4891                    })?
 4892                    .await
 4893            })
 4894        } else if self.mode.is_local() {
 4895            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4896                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4897                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4898            }) else {
 4899                return Task::ready(Ok(ProjectTransaction::default()));
 4900            };
 4901            cx.spawn(async move |this,  cx| {
 4902                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4903                    .await
 4904                    .context("resolving a code action")?;
 4905                if let Some(edit) = action.lsp_action.edit()
 4906                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4907                        return LocalLspStore::deserialize_workspace_edit(
 4908                            this.upgrade().context("no app present")?,
 4909                            edit.clone(),
 4910                            push_to_history,
 4911
 4912                            lang_server.clone(),
 4913                            cx,
 4914                        )
 4915                        .await;
 4916                    }
 4917
 4918                if let Some(command) = action.lsp_action.command() {
 4919                    let server_capabilities = lang_server.capabilities();
 4920                    let available_commands = server_capabilities
 4921                        .execute_command_provider
 4922                        .as_ref()
 4923                        .map(|options| options.commands.as_slice())
 4924                        .unwrap_or_default();
 4925                    if available_commands.contains(&command.command) {
 4926                        this.update(cx, |this, _| {
 4927                            this.as_local_mut()
 4928                                .unwrap()
 4929                                .last_workspace_edits_by_language_server
 4930                                .remove(&lang_server.server_id());
 4931                        })?;
 4932
 4933                        let _result = lang_server
 4934                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4935                                command: command.command.clone(),
 4936                                arguments: command.arguments.clone().unwrap_or_default(),
 4937                                ..lsp::ExecuteCommandParams::default()
 4938                            })
 4939                            .await.into_response()
 4940                            .context("execute command")?;
 4941
 4942                        return this.update(cx, |this, _| {
 4943                            this.as_local_mut()
 4944                                .unwrap()
 4945                                .last_workspace_edits_by_language_server
 4946                                .remove(&lang_server.server_id())
 4947                                .unwrap_or_default()
 4948                        });
 4949                    } else {
 4950                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4951                    }
 4952                }
 4953
 4954                Ok(ProjectTransaction::default())
 4955            })
 4956        } else {
 4957            Task::ready(Err(anyhow!("no upstream client and not local")))
 4958        }
 4959    }
 4960
 4961    pub fn apply_code_action_kind(
 4962        &mut self,
 4963        buffers: HashSet<Entity<Buffer>>,
 4964        kind: CodeActionKind,
 4965        push_to_history: bool,
 4966        cx: &mut Context<Self>,
 4967    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4968        if self.as_local().is_some() {
 4969            cx.spawn(async move |lsp_store, cx| {
 4970                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4971                let result = LocalLspStore::execute_code_action_kind_locally(
 4972                    lsp_store.clone(),
 4973                    buffers,
 4974                    kind,
 4975                    push_to_history,
 4976                    cx,
 4977                )
 4978                .await;
 4979                lsp_store.update(cx, |lsp_store, _| {
 4980                    lsp_store.update_last_formatting_failure(&result);
 4981                })?;
 4982                result
 4983            })
 4984        } else if let Some((client, project_id)) = self.upstream_client() {
 4985            let buffer_store = self.buffer_store();
 4986            cx.spawn(async move |lsp_store, cx| {
 4987                let result = client
 4988                    .request(proto::ApplyCodeActionKind {
 4989                        project_id,
 4990                        kind: kind.as_str().to_owned(),
 4991                        buffer_ids: buffers
 4992                            .iter()
 4993                            .map(|buffer| {
 4994                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4995                            })
 4996                            .collect::<Result<_>>()?,
 4997                    })
 4998                    .await
 4999                    .and_then(|result| result.transaction.context("missing transaction"));
 5000                lsp_store.update(cx, |lsp_store, _| {
 5001                    lsp_store.update_last_formatting_failure(&result);
 5002                })?;
 5003
 5004                let transaction_response = result?;
 5005                buffer_store
 5006                    .update(cx, |buffer_store, cx| {
 5007                        buffer_store.deserialize_project_transaction(
 5008                            transaction_response,
 5009                            push_to_history,
 5010                            cx,
 5011                        )
 5012                    })?
 5013                    .await
 5014            })
 5015        } else {
 5016            Task::ready(Ok(ProjectTransaction::default()))
 5017        }
 5018    }
 5019
 5020    pub fn resolved_hint(
 5021        &mut self,
 5022        buffer_id: BufferId,
 5023        id: InlayId,
 5024        cx: &mut Context<Self>,
 5025    ) -> Option<ResolvedHint> {
 5026        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5027
 5028        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5029        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5030        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5031        let (server_id, resolve_data) = match &hint.resolve_state {
 5032            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5033            ResolveState::Resolving => {
 5034                return Some(ResolvedHint::Resolving(
 5035                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5036                ));
 5037            }
 5038            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5039        };
 5040
 5041        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5042        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5043        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5044            id,
 5045            cx.spawn(async move |lsp_store, cx| {
 5046                let resolved_hint = resolve_task.await;
 5047                lsp_store
 5048                    .update(cx, |lsp_store, _| {
 5049                        if let Some(old_inlay_hint) = lsp_store
 5050                            .lsp_data
 5051                            .get_mut(&buffer_id)
 5052                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5053                        {
 5054                            match resolved_hint {
 5055                                Ok(resolved_hint) => {
 5056                                    *old_inlay_hint = resolved_hint;
 5057                                }
 5058                                Err(e) => {
 5059                                    old_inlay_hint.resolve_state =
 5060                                        ResolveState::CanResolve(server_id, resolve_data);
 5061                                    log::error!("Inlay hint resolve failed: {e:#}");
 5062                                }
 5063                            }
 5064                        }
 5065                    })
 5066                    .ok();
 5067            })
 5068            .shared(),
 5069        );
 5070        debug_assert!(
 5071            previous_task.is_none(),
 5072            "Did not change hint's resolve state after spawning its resolve"
 5073        );
 5074        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5075        None
 5076    }
 5077
 5078    fn resolve_inlay_hint(
 5079        &self,
 5080        mut hint: InlayHint,
 5081        buffer: Entity<Buffer>,
 5082        server_id: LanguageServerId,
 5083        cx: &mut Context<Self>,
 5084    ) -> Task<anyhow::Result<InlayHint>> {
 5085        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5086            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5087            {
 5088                hint.resolve_state = ResolveState::Resolved;
 5089                return Task::ready(Ok(hint));
 5090            }
 5091            let request = proto::ResolveInlayHint {
 5092                project_id,
 5093                buffer_id: buffer.read(cx).remote_id().into(),
 5094                language_server_id: server_id.0 as u64,
 5095                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5096            };
 5097            cx.background_spawn(async move {
 5098                let response = upstream_client
 5099                    .request(request)
 5100                    .await
 5101                    .context("inlay hints proto request")?;
 5102                match response.hint {
 5103                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5104                        .context("inlay hints proto resolve response conversion"),
 5105                    None => Ok(hint),
 5106                }
 5107            })
 5108        } else {
 5109            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5110                self.language_server_for_local_buffer(buffer, server_id, cx)
 5111                    .map(|(_, server)| server.clone())
 5112            }) else {
 5113                return Task::ready(Ok(hint));
 5114            };
 5115            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5116                return Task::ready(Ok(hint));
 5117            }
 5118            let buffer_snapshot = buffer.read(cx).snapshot();
 5119            cx.spawn(async move |_, cx| {
 5120                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5121                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5122                );
 5123                let resolved_hint = resolve_task
 5124                    .await
 5125                    .into_response()
 5126                    .context("inlay hint resolve LSP request")?;
 5127                let resolved_hint = InlayHints::lsp_to_project_hint(
 5128                    resolved_hint,
 5129                    &buffer,
 5130                    server_id,
 5131                    ResolveState::Resolved,
 5132                    false,
 5133                    cx,
 5134                )
 5135                .await?;
 5136                Ok(resolved_hint)
 5137            })
 5138        }
 5139    }
 5140
 5141    pub fn resolve_color_presentation(
 5142        &mut self,
 5143        mut color: DocumentColor,
 5144        buffer: Entity<Buffer>,
 5145        server_id: LanguageServerId,
 5146        cx: &mut Context<Self>,
 5147    ) -> Task<Result<DocumentColor>> {
 5148        if color.resolved {
 5149            return Task::ready(Ok(color));
 5150        }
 5151
 5152        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5153            let start = color.lsp_range.start;
 5154            let end = color.lsp_range.end;
 5155            let request = proto::GetColorPresentation {
 5156                project_id,
 5157                server_id: server_id.to_proto(),
 5158                buffer_id: buffer.read(cx).remote_id().into(),
 5159                color: Some(proto::ColorInformation {
 5160                    red: color.color.red,
 5161                    green: color.color.green,
 5162                    blue: color.color.blue,
 5163                    alpha: color.color.alpha,
 5164                    lsp_range_start: Some(proto::PointUtf16 {
 5165                        row: start.line,
 5166                        column: start.character,
 5167                    }),
 5168                    lsp_range_end: Some(proto::PointUtf16 {
 5169                        row: end.line,
 5170                        column: end.character,
 5171                    }),
 5172                }),
 5173            };
 5174            cx.background_spawn(async move {
 5175                let response = upstream_client
 5176                    .request(request)
 5177                    .await
 5178                    .context("color presentation proto request")?;
 5179                color.resolved = true;
 5180                color.color_presentations = response
 5181                    .presentations
 5182                    .into_iter()
 5183                    .map(|presentation| ColorPresentation {
 5184                        label: SharedString::from(presentation.label),
 5185                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5186                        additional_text_edits: presentation
 5187                            .additional_text_edits
 5188                            .into_iter()
 5189                            .filter_map(deserialize_lsp_edit)
 5190                            .collect(),
 5191                    })
 5192                    .collect();
 5193                Ok(color)
 5194            })
 5195        } else {
 5196            let path = match buffer
 5197                .update(cx, |buffer, cx| {
 5198                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5199                })
 5200                .context("buffer with the missing path")
 5201            {
 5202                Ok(path) => path,
 5203                Err(e) => return Task::ready(Err(e)),
 5204            };
 5205            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5206                self.language_server_for_local_buffer(buffer, server_id, cx)
 5207                    .map(|(_, server)| server.clone())
 5208            }) else {
 5209                return Task::ready(Ok(color));
 5210            };
 5211            cx.background_spawn(async move {
 5212                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5213                    lsp::ColorPresentationParams {
 5214                        text_document: make_text_document_identifier(&path)?,
 5215                        color: color.color,
 5216                        range: color.lsp_range,
 5217                        work_done_progress_params: Default::default(),
 5218                        partial_result_params: Default::default(),
 5219                    },
 5220                );
 5221                color.color_presentations = resolve_task
 5222                    .await
 5223                    .into_response()
 5224                    .context("color presentation resolve LSP request")?
 5225                    .into_iter()
 5226                    .map(|presentation| ColorPresentation {
 5227                        label: SharedString::from(presentation.label),
 5228                        text_edit: presentation.text_edit,
 5229                        additional_text_edits: presentation
 5230                            .additional_text_edits
 5231                            .unwrap_or_default(),
 5232                    })
 5233                    .collect();
 5234                color.resolved = true;
 5235                Ok(color)
 5236            })
 5237        }
 5238    }
 5239
 5240    pub(crate) fn linked_edits(
 5241        &mut self,
 5242        buffer: &Entity<Buffer>,
 5243        position: Anchor,
 5244        cx: &mut Context<Self>,
 5245    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5246        let snapshot = buffer.read(cx).snapshot();
 5247        let scope = snapshot.language_scope_at(position);
 5248        let Some(server_id) = self
 5249            .as_local()
 5250            .and_then(|local| {
 5251                buffer.update(cx, |buffer, cx| {
 5252                    local
 5253                        .language_servers_for_buffer(buffer, cx)
 5254                        .filter(|(_, server)| {
 5255                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5256                        })
 5257                        .filter(|(adapter, _)| {
 5258                            scope
 5259                                .as_ref()
 5260                                .map(|scope| scope.language_allowed(&adapter.name))
 5261                                .unwrap_or(true)
 5262                        })
 5263                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5264                        .next()
 5265                })
 5266            })
 5267            .or_else(|| {
 5268                self.upstream_client()
 5269                    .is_some()
 5270                    .then_some(LanguageServerToQuery::FirstCapable)
 5271            })
 5272            .filter(|_| {
 5273                maybe!({
 5274                    let language = buffer.read(cx).language_at(position)?;
 5275                    Some(
 5276                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5277                            .linked_edits,
 5278                    )
 5279                }) == Some(true)
 5280            })
 5281        else {
 5282            return Task::ready(Ok(Vec::new()));
 5283        };
 5284
 5285        self.request_lsp(
 5286            buffer.clone(),
 5287            server_id,
 5288            LinkedEditingRange { position },
 5289            cx,
 5290        )
 5291    }
 5292
 5293    fn apply_on_type_formatting(
 5294        &mut self,
 5295        buffer: Entity<Buffer>,
 5296        position: Anchor,
 5297        trigger: String,
 5298        cx: &mut Context<Self>,
 5299    ) -> Task<Result<Option<Transaction>>> {
 5300        if let Some((client, project_id)) = self.upstream_client() {
 5301            if !self.check_if_capable_for_proto_request(
 5302                &buffer,
 5303                |capabilities| {
 5304                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5305                },
 5306                cx,
 5307            ) {
 5308                return Task::ready(Ok(None));
 5309            }
 5310            let request = proto::OnTypeFormatting {
 5311                project_id,
 5312                buffer_id: buffer.read(cx).remote_id().into(),
 5313                position: Some(serialize_anchor(&position)),
 5314                trigger,
 5315                version: serialize_version(&buffer.read(cx).version()),
 5316            };
 5317            cx.background_spawn(async move {
 5318                client
 5319                    .request(request)
 5320                    .await?
 5321                    .transaction
 5322                    .map(language::proto::deserialize_transaction)
 5323                    .transpose()
 5324            })
 5325        } else if let Some(local) = self.as_local_mut() {
 5326            let buffer_id = buffer.read(cx).remote_id();
 5327            local.buffers_being_formatted.insert(buffer_id);
 5328            cx.spawn(async move |this, cx| {
 5329                let _cleanup = defer({
 5330                    let this = this.clone();
 5331                    let mut cx = cx.clone();
 5332                    move || {
 5333                        this.update(&mut cx, |this, _| {
 5334                            if let Some(local) = this.as_local_mut() {
 5335                                local.buffers_being_formatted.remove(&buffer_id);
 5336                            }
 5337                        })
 5338                        .ok();
 5339                    }
 5340                });
 5341
 5342                buffer
 5343                    .update(cx, |buffer, _| {
 5344                        buffer.wait_for_edits(Some(position.timestamp))
 5345                    })?
 5346                    .await?;
 5347                this.update(cx, |this, cx| {
 5348                    let position = position.to_point_utf16(buffer.read(cx));
 5349                    this.on_type_format(buffer, position, trigger, false, cx)
 5350                })?
 5351                .await
 5352            })
 5353        } else {
 5354            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5355        }
 5356    }
 5357
 5358    pub fn on_type_format<T: ToPointUtf16>(
 5359        &mut self,
 5360        buffer: Entity<Buffer>,
 5361        position: T,
 5362        trigger: String,
 5363        push_to_history: bool,
 5364        cx: &mut Context<Self>,
 5365    ) -> Task<Result<Option<Transaction>>> {
 5366        let position = position.to_point_utf16(buffer.read(cx));
 5367        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5368    }
 5369
 5370    fn on_type_format_impl(
 5371        &mut self,
 5372        buffer: Entity<Buffer>,
 5373        position: PointUtf16,
 5374        trigger: String,
 5375        push_to_history: bool,
 5376        cx: &mut Context<Self>,
 5377    ) -> Task<Result<Option<Transaction>>> {
 5378        let options = buffer.update(cx, |buffer, cx| {
 5379            lsp_command::lsp_formatting_options(
 5380                language_settings(
 5381                    buffer.language_at(position).map(|l| l.name()),
 5382                    buffer.file(),
 5383                    cx,
 5384                )
 5385                .as_ref(),
 5386            )
 5387        });
 5388
 5389        cx.spawn(async move |this, cx| {
 5390            if let Some(waiter) =
 5391                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5392            {
 5393                waiter.await?;
 5394            }
 5395            cx.update(|cx| {
 5396                this.update(cx, |this, cx| {
 5397                    this.request_lsp(
 5398                        buffer.clone(),
 5399                        LanguageServerToQuery::FirstCapable,
 5400                        OnTypeFormatting {
 5401                            position,
 5402                            trigger,
 5403                            options,
 5404                            push_to_history,
 5405                        },
 5406                        cx,
 5407                    )
 5408                })
 5409            })??
 5410            .await
 5411        })
 5412    }
 5413
 5414    pub fn definitions(
 5415        &mut self,
 5416        buffer: &Entity<Buffer>,
 5417        position: PointUtf16,
 5418        cx: &mut Context<Self>,
 5419    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5420        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5421            let request = GetDefinitions { position };
 5422            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5423                return Task::ready(Ok(None));
 5424            }
 5425            let request_task = upstream_client.request_lsp(
 5426                project_id,
 5427                None,
 5428                LSP_REQUEST_TIMEOUT,
 5429                cx.background_executor().clone(),
 5430                request.to_proto(project_id, buffer.read(cx)),
 5431            );
 5432            let buffer = buffer.clone();
 5433            cx.spawn(async move |weak_lsp_store, cx| {
 5434                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5435                    return Ok(None);
 5436                };
 5437                let Some(responses) = request_task.await? else {
 5438                    return Ok(None);
 5439                };
 5440                let actions = join_all(responses.payload.into_iter().map(|response| {
 5441                    GetDefinitions { position }.response_from_proto(
 5442                        response.response,
 5443                        lsp_store.clone(),
 5444                        buffer.clone(),
 5445                        cx.clone(),
 5446                    )
 5447                }))
 5448                .await;
 5449
 5450                Ok(Some(
 5451                    actions
 5452                        .into_iter()
 5453                        .collect::<Result<Vec<Vec<_>>>>()?
 5454                        .into_iter()
 5455                        .flatten()
 5456                        .dedup()
 5457                        .collect(),
 5458                ))
 5459            })
 5460        } else {
 5461            let definitions_task = self.request_multiple_lsp_locally(
 5462                buffer,
 5463                Some(position),
 5464                GetDefinitions { position },
 5465                cx,
 5466            );
 5467            cx.background_spawn(async move {
 5468                Ok(Some(
 5469                    definitions_task
 5470                        .await
 5471                        .into_iter()
 5472                        .flat_map(|(_, definitions)| definitions)
 5473                        .dedup()
 5474                        .collect(),
 5475                ))
 5476            })
 5477        }
 5478    }
 5479
 5480    pub fn declarations(
 5481        &mut self,
 5482        buffer: &Entity<Buffer>,
 5483        position: PointUtf16,
 5484        cx: &mut Context<Self>,
 5485    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5486        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5487            let request = GetDeclarations { position };
 5488            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5489                return Task::ready(Ok(None));
 5490            }
 5491            let request_task = upstream_client.request_lsp(
 5492                project_id,
 5493                None,
 5494                LSP_REQUEST_TIMEOUT,
 5495                cx.background_executor().clone(),
 5496                request.to_proto(project_id, buffer.read(cx)),
 5497            );
 5498            let buffer = buffer.clone();
 5499            cx.spawn(async move |weak_lsp_store, cx| {
 5500                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5501                    return Ok(None);
 5502                };
 5503                let Some(responses) = request_task.await? else {
 5504                    return Ok(None);
 5505                };
 5506                let actions = join_all(responses.payload.into_iter().map(|response| {
 5507                    GetDeclarations { position }.response_from_proto(
 5508                        response.response,
 5509                        lsp_store.clone(),
 5510                        buffer.clone(),
 5511                        cx.clone(),
 5512                    )
 5513                }))
 5514                .await;
 5515
 5516                Ok(Some(
 5517                    actions
 5518                        .into_iter()
 5519                        .collect::<Result<Vec<Vec<_>>>>()?
 5520                        .into_iter()
 5521                        .flatten()
 5522                        .dedup()
 5523                        .collect(),
 5524                ))
 5525            })
 5526        } else {
 5527            let declarations_task = self.request_multiple_lsp_locally(
 5528                buffer,
 5529                Some(position),
 5530                GetDeclarations { position },
 5531                cx,
 5532            );
 5533            cx.background_spawn(async move {
 5534                Ok(Some(
 5535                    declarations_task
 5536                        .await
 5537                        .into_iter()
 5538                        .flat_map(|(_, declarations)| declarations)
 5539                        .dedup()
 5540                        .collect(),
 5541                ))
 5542            })
 5543        }
 5544    }
 5545
 5546    pub fn type_definitions(
 5547        &mut self,
 5548        buffer: &Entity<Buffer>,
 5549        position: PointUtf16,
 5550        cx: &mut Context<Self>,
 5551    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5552        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5553            let request = GetTypeDefinitions { position };
 5554            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5555                return Task::ready(Ok(None));
 5556            }
 5557            let request_task = upstream_client.request_lsp(
 5558                project_id,
 5559                None,
 5560                LSP_REQUEST_TIMEOUT,
 5561                cx.background_executor().clone(),
 5562                request.to_proto(project_id, buffer.read(cx)),
 5563            );
 5564            let buffer = buffer.clone();
 5565            cx.spawn(async move |weak_lsp_store, cx| {
 5566                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5567                    return Ok(None);
 5568                };
 5569                let Some(responses) = request_task.await? else {
 5570                    return Ok(None);
 5571                };
 5572                let actions = join_all(responses.payload.into_iter().map(|response| {
 5573                    GetTypeDefinitions { position }.response_from_proto(
 5574                        response.response,
 5575                        lsp_store.clone(),
 5576                        buffer.clone(),
 5577                        cx.clone(),
 5578                    )
 5579                }))
 5580                .await;
 5581
 5582                Ok(Some(
 5583                    actions
 5584                        .into_iter()
 5585                        .collect::<Result<Vec<Vec<_>>>>()?
 5586                        .into_iter()
 5587                        .flatten()
 5588                        .dedup()
 5589                        .collect(),
 5590                ))
 5591            })
 5592        } else {
 5593            let type_definitions_task = self.request_multiple_lsp_locally(
 5594                buffer,
 5595                Some(position),
 5596                GetTypeDefinitions { position },
 5597                cx,
 5598            );
 5599            cx.background_spawn(async move {
 5600                Ok(Some(
 5601                    type_definitions_task
 5602                        .await
 5603                        .into_iter()
 5604                        .flat_map(|(_, type_definitions)| type_definitions)
 5605                        .dedup()
 5606                        .collect(),
 5607                ))
 5608            })
 5609        }
 5610    }
 5611
 5612    pub fn implementations(
 5613        &mut self,
 5614        buffer: &Entity<Buffer>,
 5615        position: PointUtf16,
 5616        cx: &mut Context<Self>,
 5617    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5618        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5619            let request = GetImplementations { position };
 5620            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5621                return Task::ready(Ok(None));
 5622            }
 5623            let request_task = upstream_client.request_lsp(
 5624                project_id,
 5625                None,
 5626                LSP_REQUEST_TIMEOUT,
 5627                cx.background_executor().clone(),
 5628                request.to_proto(project_id, buffer.read(cx)),
 5629            );
 5630            let buffer = buffer.clone();
 5631            cx.spawn(async move |weak_lsp_store, cx| {
 5632                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5633                    return Ok(None);
 5634                };
 5635                let Some(responses) = request_task.await? else {
 5636                    return Ok(None);
 5637                };
 5638                let actions = join_all(responses.payload.into_iter().map(|response| {
 5639                    GetImplementations { position }.response_from_proto(
 5640                        response.response,
 5641                        lsp_store.clone(),
 5642                        buffer.clone(),
 5643                        cx.clone(),
 5644                    )
 5645                }))
 5646                .await;
 5647
 5648                Ok(Some(
 5649                    actions
 5650                        .into_iter()
 5651                        .collect::<Result<Vec<Vec<_>>>>()?
 5652                        .into_iter()
 5653                        .flatten()
 5654                        .dedup()
 5655                        .collect(),
 5656                ))
 5657            })
 5658        } else {
 5659            let implementations_task = self.request_multiple_lsp_locally(
 5660                buffer,
 5661                Some(position),
 5662                GetImplementations { position },
 5663                cx,
 5664            );
 5665            cx.background_spawn(async move {
 5666                Ok(Some(
 5667                    implementations_task
 5668                        .await
 5669                        .into_iter()
 5670                        .flat_map(|(_, implementations)| implementations)
 5671                        .dedup()
 5672                        .collect(),
 5673                ))
 5674            })
 5675        }
 5676    }
 5677
 5678    pub fn references(
 5679        &mut self,
 5680        buffer: &Entity<Buffer>,
 5681        position: PointUtf16,
 5682        cx: &mut Context<Self>,
 5683    ) -> Task<Result<Option<Vec<Location>>>> {
 5684        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5685            let request = GetReferences { position };
 5686            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5687                return Task::ready(Ok(None));
 5688            }
 5689
 5690            let request_task = upstream_client.request_lsp(
 5691                project_id,
 5692                None,
 5693                LSP_REQUEST_TIMEOUT,
 5694                cx.background_executor().clone(),
 5695                request.to_proto(project_id, buffer.read(cx)),
 5696            );
 5697            let buffer = buffer.clone();
 5698            cx.spawn(async move |weak_lsp_store, cx| {
 5699                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5700                    return Ok(None);
 5701                };
 5702                let Some(responses) = request_task.await? else {
 5703                    return Ok(None);
 5704                };
 5705
 5706                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5707                    GetReferences { position }.response_from_proto(
 5708                        lsp_response.response,
 5709                        lsp_store.clone(),
 5710                        buffer.clone(),
 5711                        cx.clone(),
 5712                    )
 5713                }))
 5714                .await
 5715                .into_iter()
 5716                .collect::<Result<Vec<Vec<_>>>>()?
 5717                .into_iter()
 5718                .flatten()
 5719                .dedup()
 5720                .collect();
 5721                Ok(Some(locations))
 5722            })
 5723        } else {
 5724            let references_task = self.request_multiple_lsp_locally(
 5725                buffer,
 5726                Some(position),
 5727                GetReferences { position },
 5728                cx,
 5729            );
 5730            cx.background_spawn(async move {
 5731                Ok(Some(
 5732                    references_task
 5733                        .await
 5734                        .into_iter()
 5735                        .flat_map(|(_, references)| references)
 5736                        .dedup()
 5737                        .collect(),
 5738                ))
 5739            })
 5740        }
 5741    }
 5742
 5743    pub fn code_actions(
 5744        &mut self,
 5745        buffer: &Entity<Buffer>,
 5746        range: Range<Anchor>,
 5747        kinds: Option<Vec<CodeActionKind>>,
 5748        cx: &mut Context<Self>,
 5749    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5750        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5751            let request = GetCodeActions {
 5752                range: range.clone(),
 5753                kinds: kinds.clone(),
 5754            };
 5755            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5756                return Task::ready(Ok(None));
 5757            }
 5758            let request_task = upstream_client.request_lsp(
 5759                project_id,
 5760                None,
 5761                LSP_REQUEST_TIMEOUT,
 5762                cx.background_executor().clone(),
 5763                request.to_proto(project_id, buffer.read(cx)),
 5764            );
 5765            let buffer = buffer.clone();
 5766            cx.spawn(async move |weak_lsp_store, cx| {
 5767                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5768                    return Ok(None);
 5769                };
 5770                let Some(responses) = request_task.await? else {
 5771                    return Ok(None);
 5772                };
 5773                let actions = join_all(responses.payload.into_iter().map(|response| {
 5774                    GetCodeActions {
 5775                        range: range.clone(),
 5776                        kinds: kinds.clone(),
 5777                    }
 5778                    .response_from_proto(
 5779                        response.response,
 5780                        lsp_store.clone(),
 5781                        buffer.clone(),
 5782                        cx.clone(),
 5783                    )
 5784                }))
 5785                .await;
 5786
 5787                Ok(Some(
 5788                    actions
 5789                        .into_iter()
 5790                        .collect::<Result<Vec<Vec<_>>>>()?
 5791                        .into_iter()
 5792                        .flatten()
 5793                        .collect(),
 5794                ))
 5795            })
 5796        } else {
 5797            let all_actions_task = self.request_multiple_lsp_locally(
 5798                buffer,
 5799                Some(range.start),
 5800                GetCodeActions { range, kinds },
 5801                cx,
 5802            );
 5803            cx.background_spawn(async move {
 5804                Ok(Some(
 5805                    all_actions_task
 5806                        .await
 5807                        .into_iter()
 5808                        .flat_map(|(_, actions)| actions)
 5809                        .collect(),
 5810                ))
 5811            })
 5812        }
 5813    }
 5814
 5815    pub fn code_lens_actions(
 5816        &mut self,
 5817        buffer: &Entity<Buffer>,
 5818        cx: &mut Context<Self>,
 5819    ) -> CodeLensTask {
 5820        let version_queried_for = buffer.read(cx).version();
 5821        let buffer_id = buffer.read(cx).remote_id();
 5822        let existing_servers = self.as_local().map(|local| {
 5823            local
 5824                .buffers_opened_in_servers
 5825                .get(&buffer_id)
 5826                .cloned()
 5827                .unwrap_or_default()
 5828        });
 5829
 5830        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5831            if let Some(cached_lens) = &lsp_data.code_lens {
 5832                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5833                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5834                        existing_servers != cached_lens.lens.keys().copied().collect()
 5835                    });
 5836                    if !has_different_servers {
 5837                        return Task::ready(Ok(Some(
 5838                            cached_lens.lens.values().flatten().cloned().collect(),
 5839                        )))
 5840                        .shared();
 5841                    }
 5842                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5843                    if !version_queried_for.changed_since(updating_for) {
 5844                        return running_update.clone();
 5845                    }
 5846                }
 5847            }
 5848        }
 5849
 5850        let lens_lsp_data = self
 5851            .latest_lsp_data(buffer, cx)
 5852            .code_lens
 5853            .get_or_insert_default();
 5854        let buffer = buffer.clone();
 5855        let query_version_queried_for = version_queried_for.clone();
 5856        let new_task = cx
 5857            .spawn(async move |lsp_store, cx| {
 5858                cx.background_executor()
 5859                    .timer(Duration::from_millis(30))
 5860                    .await;
 5861                let fetched_lens = lsp_store
 5862                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5863                    .map_err(Arc::new)?
 5864                    .await
 5865                    .context("fetching code lens")
 5866                    .map_err(Arc::new);
 5867                let fetched_lens = match fetched_lens {
 5868                    Ok(fetched_lens) => fetched_lens,
 5869                    Err(e) => {
 5870                        lsp_store
 5871                            .update(cx, |lsp_store, _| {
 5872                                if let Some(lens_lsp_data) = lsp_store
 5873                                    .lsp_data
 5874                                    .get_mut(&buffer_id)
 5875                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5876                                {
 5877                                    lens_lsp_data.update = None;
 5878                                }
 5879                            })
 5880                            .ok();
 5881                        return Err(e);
 5882                    }
 5883                };
 5884
 5885                lsp_store
 5886                    .update(cx, |lsp_store, _| {
 5887                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5888                        let code_lens = lsp_data.code_lens.as_mut()?;
 5889                        if let Some(fetched_lens) = fetched_lens {
 5890                            if lsp_data.buffer_version == query_version_queried_for {
 5891                                code_lens.lens.extend(fetched_lens);
 5892                            } else if !lsp_data
 5893                                .buffer_version
 5894                                .changed_since(&query_version_queried_for)
 5895                            {
 5896                                lsp_data.buffer_version = query_version_queried_for;
 5897                                code_lens.lens = fetched_lens;
 5898                            }
 5899                        }
 5900                        code_lens.update = None;
 5901                        Some(code_lens.lens.values().flatten().cloned().collect())
 5902                    })
 5903                    .map_err(Arc::new)
 5904            })
 5905            .shared();
 5906        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5907        new_task
 5908    }
 5909
 5910    fn fetch_code_lens(
 5911        &mut self,
 5912        buffer: &Entity<Buffer>,
 5913        cx: &mut Context<Self>,
 5914    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5915        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5916            let request = GetCodeLens;
 5917            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5918                return Task::ready(Ok(None));
 5919            }
 5920            let request_task = upstream_client.request_lsp(
 5921                project_id,
 5922                None,
 5923                LSP_REQUEST_TIMEOUT,
 5924                cx.background_executor().clone(),
 5925                request.to_proto(project_id, buffer.read(cx)),
 5926            );
 5927            let buffer = buffer.clone();
 5928            cx.spawn(async move |weak_lsp_store, cx| {
 5929                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5930                    return Ok(None);
 5931                };
 5932                let Some(responses) = request_task.await? else {
 5933                    return Ok(None);
 5934                };
 5935
 5936                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5937                    let lsp_store = lsp_store.clone();
 5938                    let buffer = buffer.clone();
 5939                    let cx = cx.clone();
 5940                    async move {
 5941                        (
 5942                            LanguageServerId::from_proto(response.server_id),
 5943                            GetCodeLens
 5944                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5945                                .await,
 5946                        )
 5947                    }
 5948                }))
 5949                .await;
 5950
 5951                let mut has_errors = false;
 5952                let code_lens_actions = code_lens_actions
 5953                    .into_iter()
 5954                    .filter_map(|(server_id, code_lens)| match code_lens {
 5955                        Ok(code_lens) => Some((server_id, code_lens)),
 5956                        Err(e) => {
 5957                            has_errors = true;
 5958                            log::error!("{e:#}");
 5959                            None
 5960                        }
 5961                    })
 5962                    .collect::<HashMap<_, _>>();
 5963                anyhow::ensure!(
 5964                    !has_errors || !code_lens_actions.is_empty(),
 5965                    "Failed to fetch code lens"
 5966                );
 5967                Ok(Some(code_lens_actions))
 5968            })
 5969        } else {
 5970            let code_lens_actions_task =
 5971                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5972            cx.background_spawn(async move {
 5973                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5974            })
 5975        }
 5976    }
 5977
 5978    #[inline(never)]
 5979    pub fn completions(
 5980        &self,
 5981        buffer: &Entity<Buffer>,
 5982        position: PointUtf16,
 5983        context: CompletionContext,
 5984        cx: &mut Context<Self>,
 5985    ) -> Task<Result<Vec<CompletionResponse>>> {
 5986        let language_registry = self.languages.clone();
 5987
 5988        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5989            let snapshot = buffer.read(cx).snapshot();
 5990            let offset = position.to_offset(&snapshot);
 5991            let scope = snapshot.language_scope_at(offset);
 5992            let capable_lsps = self.all_capable_for_proto_request(
 5993                buffer,
 5994                |server_name, capabilities| {
 5995                    capabilities.completion_provider.is_some()
 5996                        && scope
 5997                            .as_ref()
 5998                            .map(|scope| scope.language_allowed(server_name))
 5999                            .unwrap_or(true)
 6000                },
 6001                cx,
 6002            );
 6003            if capable_lsps.is_empty() {
 6004                return Task::ready(Ok(Vec::new()));
 6005            }
 6006
 6007            let language = buffer.read(cx).language().cloned();
 6008
 6009            // In the future, we should provide project guests with the names of LSP adapters,
 6010            // so that they can use the correct LSP adapter when computing labels. For now,
 6011            // guests just use the first LSP adapter associated with the buffer's language.
 6012            let lsp_adapter = language.as_ref().and_then(|language| {
 6013                language_registry
 6014                    .lsp_adapters(&language.name())
 6015                    .first()
 6016                    .cloned()
 6017            });
 6018
 6019            let buffer = buffer.clone();
 6020
 6021            cx.spawn(async move |this, cx| {
 6022                let requests = join_all(
 6023                    capable_lsps
 6024                        .into_iter()
 6025                        .map(|id| {
 6026                            let request = GetCompletions {
 6027                                position,
 6028                                context: context.clone(),
 6029                                server_id: Some(id),
 6030                            };
 6031                            let buffer = buffer.clone();
 6032                            let language = language.clone();
 6033                            let lsp_adapter = lsp_adapter.clone();
 6034                            let upstream_client = upstream_client.clone();
 6035                            let response = this
 6036                                .update(cx, |this, cx| {
 6037                                    this.send_lsp_proto_request(
 6038                                        buffer,
 6039                                        upstream_client,
 6040                                        project_id,
 6041                                        request,
 6042                                        cx,
 6043                                    )
 6044                                })
 6045                                .log_err();
 6046                            async move {
 6047                                let response = response?.await.log_err()?;
 6048
 6049                                let completions = populate_labels_for_completions(
 6050                                    response.completions,
 6051                                    language,
 6052                                    lsp_adapter,
 6053                                )
 6054                                .await;
 6055
 6056                                Some(CompletionResponse {
 6057                                    completions,
 6058                                    display_options: CompletionDisplayOptions::default(),
 6059                                    is_incomplete: response.is_incomplete,
 6060                                })
 6061                            }
 6062                        })
 6063                        .collect::<Vec<_>>(),
 6064                );
 6065                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6066            })
 6067        } else if let Some(local) = self.as_local() {
 6068            let snapshot = buffer.read(cx).snapshot();
 6069            let offset = position.to_offset(&snapshot);
 6070            let scope = snapshot.language_scope_at(offset);
 6071            let language = snapshot.language().cloned();
 6072            let completion_settings = language_settings(
 6073                language.as_ref().map(|language| language.name()),
 6074                buffer.read(cx).file(),
 6075                cx,
 6076            )
 6077            .completions
 6078            .clone();
 6079            if !completion_settings.lsp {
 6080                return Task::ready(Ok(Vec::new()));
 6081            }
 6082
 6083            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6084                local
 6085                    .language_servers_for_buffer(buffer, cx)
 6086                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6087                    .filter(|(adapter, _)| {
 6088                        scope
 6089                            .as_ref()
 6090                            .map(|scope| scope.language_allowed(&adapter.name))
 6091                            .unwrap_or(true)
 6092                    })
 6093                    .map(|(_, server)| server.server_id())
 6094                    .collect()
 6095            });
 6096
 6097            let buffer = buffer.clone();
 6098            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6099            let lsp_timeout = if lsp_timeout > 0 {
 6100                Some(Duration::from_millis(lsp_timeout))
 6101            } else {
 6102                None
 6103            };
 6104            cx.spawn(async move |this,  cx| {
 6105                let mut tasks = Vec::with_capacity(server_ids.len());
 6106                this.update(cx, |lsp_store, cx| {
 6107                    for server_id in server_ids {
 6108                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6109                        let lsp_timeout = lsp_timeout
 6110                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6111                        let mut timeout = cx.background_spawn(async move {
 6112                            match lsp_timeout {
 6113                                Some(lsp_timeout) => {
 6114                                    lsp_timeout.await;
 6115                                    true
 6116                                },
 6117                                None => false,
 6118                            }
 6119                        }).fuse();
 6120                        let mut lsp_request = lsp_store.request_lsp(
 6121                            buffer.clone(),
 6122                            LanguageServerToQuery::Other(server_id),
 6123                            GetCompletions {
 6124                                position,
 6125                                context: context.clone(),
 6126                                server_id: Some(server_id),
 6127                            },
 6128                            cx,
 6129                        ).fuse();
 6130                        let new_task = cx.background_spawn(async move {
 6131                            select_biased! {
 6132                                response = lsp_request => anyhow::Ok(Some(response?)),
 6133                                timeout_happened = timeout => {
 6134                                    if timeout_happened {
 6135                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6136                                        Ok(None)
 6137                                    } else {
 6138                                        let completions = lsp_request.await?;
 6139                                        Ok(Some(completions))
 6140                                    }
 6141                                },
 6142                            }
 6143                        });
 6144                        tasks.push((lsp_adapter, new_task));
 6145                    }
 6146                })?;
 6147
 6148                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6149                    let completion_response = task.await.ok()??;
 6150                    let completions = populate_labels_for_completions(
 6151                            completion_response.completions,
 6152                            language.clone(),
 6153                            lsp_adapter,
 6154                        )
 6155                        .await;
 6156                    Some(CompletionResponse {
 6157                        completions,
 6158                        display_options: CompletionDisplayOptions::default(),
 6159                        is_incomplete: completion_response.is_incomplete,
 6160                    })
 6161                });
 6162
 6163                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6164
 6165                Ok(responses.into_iter().flatten().collect())
 6166            })
 6167        } else {
 6168            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6169        }
 6170    }
 6171
 6172    pub fn resolve_completions(
 6173        &self,
 6174        buffer: Entity<Buffer>,
 6175        completion_indices: Vec<usize>,
 6176        completions: Rc<RefCell<Box<[Completion]>>>,
 6177        cx: &mut Context<Self>,
 6178    ) -> Task<Result<bool>> {
 6179        let client = self.upstream_client();
 6180        let buffer_id = buffer.read(cx).remote_id();
 6181        let buffer_snapshot = buffer.read(cx).snapshot();
 6182
 6183        if !self.check_if_capable_for_proto_request(
 6184            &buffer,
 6185            GetCompletions::can_resolve_completions,
 6186            cx,
 6187        ) {
 6188            return Task::ready(Ok(false));
 6189        }
 6190        cx.spawn(async move |lsp_store, cx| {
 6191            let mut did_resolve = false;
 6192            if let Some((client, project_id)) = client {
 6193                for completion_index in completion_indices {
 6194                    let server_id = {
 6195                        let completion = &completions.borrow()[completion_index];
 6196                        completion.source.server_id()
 6197                    };
 6198                    if let Some(server_id) = server_id {
 6199                        if Self::resolve_completion_remote(
 6200                            project_id,
 6201                            server_id,
 6202                            buffer_id,
 6203                            completions.clone(),
 6204                            completion_index,
 6205                            client.clone(),
 6206                        )
 6207                        .await
 6208                        .log_err()
 6209                        .is_some()
 6210                        {
 6211                            did_resolve = true;
 6212                        }
 6213                    } else {
 6214                        resolve_word_completion(
 6215                            &buffer_snapshot,
 6216                            &mut completions.borrow_mut()[completion_index],
 6217                        );
 6218                    }
 6219                }
 6220            } else {
 6221                for completion_index in completion_indices {
 6222                    let server_id = {
 6223                        let completion = &completions.borrow()[completion_index];
 6224                        completion.source.server_id()
 6225                    };
 6226                    if let Some(server_id) = server_id {
 6227                        let server_and_adapter = lsp_store
 6228                            .read_with(cx, |lsp_store, _| {
 6229                                let server = lsp_store.language_server_for_id(server_id)?;
 6230                                let adapter =
 6231                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6232                                Some((server, adapter))
 6233                            })
 6234                            .ok()
 6235                            .flatten();
 6236                        let Some((server, adapter)) = server_and_adapter else {
 6237                            continue;
 6238                        };
 6239
 6240                        let resolved = Self::resolve_completion_local(
 6241                            server,
 6242                            completions.clone(),
 6243                            completion_index,
 6244                        )
 6245                        .await
 6246                        .log_err()
 6247                        .is_some();
 6248                        if resolved {
 6249                            Self::regenerate_completion_labels(
 6250                                adapter,
 6251                                &buffer_snapshot,
 6252                                completions.clone(),
 6253                                completion_index,
 6254                            )
 6255                            .await
 6256                            .log_err();
 6257                            did_resolve = true;
 6258                        }
 6259                    } else {
 6260                        resolve_word_completion(
 6261                            &buffer_snapshot,
 6262                            &mut completions.borrow_mut()[completion_index],
 6263                        );
 6264                    }
 6265                }
 6266            }
 6267
 6268            Ok(did_resolve)
 6269        })
 6270    }
 6271
 6272    async fn resolve_completion_local(
 6273        server: Arc<lsp::LanguageServer>,
 6274        completions: Rc<RefCell<Box<[Completion]>>>,
 6275        completion_index: usize,
 6276    ) -> Result<()> {
 6277        let server_id = server.server_id();
 6278        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6279            return Ok(());
 6280        }
 6281
 6282        let request = {
 6283            let completion = &completions.borrow()[completion_index];
 6284            match &completion.source {
 6285                CompletionSource::Lsp {
 6286                    lsp_completion,
 6287                    resolved,
 6288                    server_id: completion_server_id,
 6289                    ..
 6290                } => {
 6291                    if *resolved {
 6292                        return Ok(());
 6293                    }
 6294                    anyhow::ensure!(
 6295                        server_id == *completion_server_id,
 6296                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6297                    );
 6298                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6299                }
 6300                CompletionSource::BufferWord { .. }
 6301                | CompletionSource::Dap { .. }
 6302                | CompletionSource::Custom => {
 6303                    return Ok(());
 6304                }
 6305            }
 6306        };
 6307        let resolved_completion = request
 6308            .await
 6309            .into_response()
 6310            .context("resolve completion")?;
 6311
 6312        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6313        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6314
 6315        let mut completions = completions.borrow_mut();
 6316        let completion = &mut completions[completion_index];
 6317        if let CompletionSource::Lsp {
 6318            lsp_completion,
 6319            resolved,
 6320            server_id: completion_server_id,
 6321            ..
 6322        } = &mut completion.source
 6323        {
 6324            if *resolved {
 6325                return Ok(());
 6326            }
 6327            anyhow::ensure!(
 6328                server_id == *completion_server_id,
 6329                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6330            );
 6331            *lsp_completion = Box::new(resolved_completion);
 6332            *resolved = true;
 6333        }
 6334        Ok(())
 6335    }
 6336
 6337    async fn regenerate_completion_labels(
 6338        adapter: Arc<CachedLspAdapter>,
 6339        snapshot: &BufferSnapshot,
 6340        completions: Rc<RefCell<Box<[Completion]>>>,
 6341        completion_index: usize,
 6342    ) -> Result<()> {
 6343        let completion_item = completions.borrow()[completion_index]
 6344            .source
 6345            .lsp_completion(true)
 6346            .map(Cow::into_owned);
 6347        if let Some(lsp_documentation) = completion_item
 6348            .as_ref()
 6349            .and_then(|completion_item| completion_item.documentation.clone())
 6350        {
 6351            let mut completions = completions.borrow_mut();
 6352            let completion = &mut completions[completion_index];
 6353            completion.documentation = Some(lsp_documentation.into());
 6354        } else {
 6355            let mut completions = completions.borrow_mut();
 6356            let completion = &mut completions[completion_index];
 6357            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6358        }
 6359
 6360        let mut new_label = match completion_item {
 6361            Some(completion_item) => {
 6362                // 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
 6363                // So we have to update the label here anyway...
 6364                let language = snapshot.language();
 6365                match language {
 6366                    Some(language) => {
 6367                        adapter
 6368                            .labels_for_completions(
 6369                                std::slice::from_ref(&completion_item),
 6370                                language,
 6371                            )
 6372                            .await?
 6373                    }
 6374                    None => Vec::new(),
 6375                }
 6376                .pop()
 6377                .flatten()
 6378                .unwrap_or_else(|| {
 6379                    CodeLabel::fallback_for_completion(
 6380                        &completion_item,
 6381                        language.map(|language| language.as_ref()),
 6382                    )
 6383                })
 6384            }
 6385            None => CodeLabel::plain(
 6386                completions.borrow()[completion_index].new_text.clone(),
 6387                None,
 6388            ),
 6389        };
 6390        ensure_uniform_list_compatible_label(&mut new_label);
 6391
 6392        let mut completions = completions.borrow_mut();
 6393        let completion = &mut completions[completion_index];
 6394        if completion.label.filter_text() == new_label.filter_text() {
 6395            completion.label = new_label;
 6396        } else {
 6397            log::error!(
 6398                "Resolved completion changed display label from {} to {}. \
 6399                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6400                completion.label.text(),
 6401                new_label.text(),
 6402                completion.label.filter_text(),
 6403                new_label.filter_text()
 6404            );
 6405        }
 6406
 6407        Ok(())
 6408    }
 6409
 6410    async fn resolve_completion_remote(
 6411        project_id: u64,
 6412        server_id: LanguageServerId,
 6413        buffer_id: BufferId,
 6414        completions: Rc<RefCell<Box<[Completion]>>>,
 6415        completion_index: usize,
 6416        client: AnyProtoClient,
 6417    ) -> Result<()> {
 6418        let lsp_completion = {
 6419            let completion = &completions.borrow()[completion_index];
 6420            match &completion.source {
 6421                CompletionSource::Lsp {
 6422                    lsp_completion,
 6423                    resolved,
 6424                    server_id: completion_server_id,
 6425                    ..
 6426                } => {
 6427                    anyhow::ensure!(
 6428                        server_id == *completion_server_id,
 6429                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6430                    );
 6431                    if *resolved {
 6432                        return Ok(());
 6433                    }
 6434                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6435                }
 6436                CompletionSource::Custom
 6437                | CompletionSource::Dap { .. }
 6438                | CompletionSource::BufferWord { .. } => {
 6439                    return Ok(());
 6440                }
 6441            }
 6442        };
 6443        let request = proto::ResolveCompletionDocumentation {
 6444            project_id,
 6445            language_server_id: server_id.0 as u64,
 6446            lsp_completion,
 6447            buffer_id: buffer_id.into(),
 6448        };
 6449
 6450        let response = client
 6451            .request(request)
 6452            .await
 6453            .context("completion documentation resolve proto request")?;
 6454        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6455
 6456        let documentation = if response.documentation.is_empty() {
 6457            CompletionDocumentation::Undocumented
 6458        } else if response.documentation_is_markdown {
 6459            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6460        } else if response.documentation.lines().count() <= 1 {
 6461            CompletionDocumentation::SingleLine(response.documentation.into())
 6462        } else {
 6463            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6464        };
 6465
 6466        let mut completions = completions.borrow_mut();
 6467        let completion = &mut completions[completion_index];
 6468        completion.documentation = Some(documentation);
 6469        if let CompletionSource::Lsp {
 6470            insert_range,
 6471            lsp_completion,
 6472            resolved,
 6473            server_id: completion_server_id,
 6474            lsp_defaults: _,
 6475        } = &mut completion.source
 6476        {
 6477            let completion_insert_range = response
 6478                .old_insert_start
 6479                .and_then(deserialize_anchor)
 6480                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6481            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6482
 6483            if *resolved {
 6484                return Ok(());
 6485            }
 6486            anyhow::ensure!(
 6487                server_id == *completion_server_id,
 6488                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6489            );
 6490            *lsp_completion = Box::new(resolved_lsp_completion);
 6491            *resolved = true;
 6492        }
 6493
 6494        let replace_range = response
 6495            .old_replace_start
 6496            .and_then(deserialize_anchor)
 6497            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6498        if let Some((old_replace_start, old_replace_end)) = replace_range
 6499            && !response.new_text.is_empty()
 6500        {
 6501            completion.new_text = response.new_text;
 6502            completion.replace_range = old_replace_start..old_replace_end;
 6503        }
 6504
 6505        Ok(())
 6506    }
 6507
 6508    pub fn apply_additional_edits_for_completion(
 6509        &self,
 6510        buffer_handle: Entity<Buffer>,
 6511        completions: Rc<RefCell<Box<[Completion]>>>,
 6512        completion_index: usize,
 6513        push_to_history: bool,
 6514        cx: &mut Context<Self>,
 6515    ) -> Task<Result<Option<Transaction>>> {
 6516        if let Some((client, project_id)) = self.upstream_client() {
 6517            let buffer = buffer_handle.read(cx);
 6518            let buffer_id = buffer.remote_id();
 6519            cx.spawn(async move |_, cx| {
 6520                let request = {
 6521                    let completion = completions.borrow()[completion_index].clone();
 6522                    proto::ApplyCompletionAdditionalEdits {
 6523                        project_id,
 6524                        buffer_id: buffer_id.into(),
 6525                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6526                            replace_range: completion.replace_range,
 6527                            new_text: completion.new_text,
 6528                            source: completion.source,
 6529                        })),
 6530                    }
 6531                };
 6532
 6533                if let Some(transaction) = client.request(request).await?.transaction {
 6534                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6535                    buffer_handle
 6536                        .update(cx, |buffer, _| {
 6537                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6538                        })?
 6539                        .await?;
 6540                    if push_to_history {
 6541                        buffer_handle.update(cx, |buffer, _| {
 6542                            buffer.push_transaction(transaction.clone(), Instant::now());
 6543                            buffer.finalize_last_transaction();
 6544                        })?;
 6545                    }
 6546                    Ok(Some(transaction))
 6547                } else {
 6548                    Ok(None)
 6549                }
 6550            })
 6551        } else {
 6552            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6553                let completion = &completions.borrow()[completion_index];
 6554                let server_id = completion.source.server_id()?;
 6555                Some(
 6556                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6557                        .1
 6558                        .clone(),
 6559                )
 6560            }) else {
 6561                return Task::ready(Ok(None));
 6562            };
 6563
 6564            cx.spawn(async move |this, cx| {
 6565                Self::resolve_completion_local(
 6566                    server.clone(),
 6567                    completions.clone(),
 6568                    completion_index,
 6569                )
 6570                .await
 6571                .context("resolving completion")?;
 6572                let completion = completions.borrow()[completion_index].clone();
 6573                let additional_text_edits = completion
 6574                    .source
 6575                    .lsp_completion(true)
 6576                    .as_ref()
 6577                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6578                if let Some(edits) = additional_text_edits {
 6579                    let edits = this
 6580                        .update(cx, |this, cx| {
 6581                            this.as_local_mut().unwrap().edits_from_lsp(
 6582                                &buffer_handle,
 6583                                edits,
 6584                                server.server_id(),
 6585                                None,
 6586                                cx,
 6587                            )
 6588                        })?
 6589                        .await?;
 6590
 6591                    buffer_handle.update(cx, |buffer, cx| {
 6592                        buffer.finalize_last_transaction();
 6593                        buffer.start_transaction();
 6594
 6595                        for (range, text) in edits {
 6596                            let primary = &completion.replace_range;
 6597
 6598                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6599                            // and the primary completion is just an insertion (empty range), then this is likely
 6600                            // an auto-import scenario and should not be considered overlapping
 6601                            // https://github.com/zed-industries/zed/issues/26136
 6602                            let is_file_start_auto_import = {
 6603                                let snapshot = buffer.snapshot();
 6604                                let primary_start_point = primary.start.to_point(&snapshot);
 6605                                let range_start_point = range.start.to_point(&snapshot);
 6606
 6607                                let result = primary_start_point.row == 0
 6608                                    && primary_start_point.column == 0
 6609                                    && range_start_point.row == 0
 6610                                    && range_start_point.column == 0;
 6611
 6612                                result
 6613                            };
 6614
 6615                            let has_overlap = if is_file_start_auto_import {
 6616                                false
 6617                            } else {
 6618                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6619                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6620                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6621                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6622                                let result = start_within || end_within;
 6623                                result
 6624                            };
 6625
 6626                            //Skip additional edits which overlap with the primary completion edit
 6627                            //https://github.com/zed-industries/zed/pull/1871
 6628                            if !has_overlap {
 6629                                buffer.edit([(range, text)], None, cx);
 6630                            }
 6631                        }
 6632
 6633                        let transaction = if buffer.end_transaction(cx).is_some() {
 6634                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6635                            if !push_to_history {
 6636                                buffer.forget_transaction(transaction.id);
 6637                            }
 6638                            Some(transaction)
 6639                        } else {
 6640                            None
 6641                        };
 6642                        Ok(transaction)
 6643                    })?
 6644                } else {
 6645                    Ok(None)
 6646                }
 6647            })
 6648        }
 6649    }
 6650
 6651    pub fn pull_diagnostics(
 6652        &mut self,
 6653        buffer: Entity<Buffer>,
 6654        cx: &mut Context<Self>,
 6655    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6656        let buffer_id = buffer.read(cx).remote_id();
 6657
 6658        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6659            let mut suitable_capabilities = None;
 6660            // Are we capable for proto request?
 6661            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6662                &buffer,
 6663                |capabilities| {
 6664                    if let Some(caps) = &capabilities.diagnostic_provider {
 6665                        suitable_capabilities = Some(caps.clone());
 6666                        true
 6667                    } else {
 6668                        false
 6669                    }
 6670                },
 6671                cx,
 6672            );
 6673            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6674            let Some(dynamic_caps) = suitable_capabilities else {
 6675                return Task::ready(Ok(None));
 6676            };
 6677            assert!(any_server_has_diagnostics_provider);
 6678
 6679            let request = GetDocumentDiagnostics {
 6680                previous_result_id: None,
 6681                dynamic_caps,
 6682            };
 6683            let request_task = client.request_lsp(
 6684                upstream_project_id,
 6685                None,
 6686                LSP_REQUEST_TIMEOUT,
 6687                cx.background_executor().clone(),
 6688                request.to_proto(upstream_project_id, buffer.read(cx)),
 6689            );
 6690            cx.background_spawn(async move {
 6691                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6692                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6693                // Do not attempt to further process the dummy responses here.
 6694                let _response = request_task.await?;
 6695                Ok(None)
 6696            })
 6697        } else {
 6698            let servers = buffer.update(cx, |buffer, cx| {
 6699                self.language_servers_for_local_buffer(buffer, cx)
 6700                    .map(|(_, server)| server.clone())
 6701                    .collect::<Vec<_>>()
 6702            });
 6703
 6704            let pull_diagnostics = servers
 6705                .into_iter()
 6706                .flat_map(|server| {
 6707                    let result = maybe!({
 6708                        let local = self.as_local()?;
 6709                        let server_id = server.server_id();
 6710                        let providers_with_identifiers = local
 6711                            .language_server_dynamic_registrations
 6712                            .get(&server_id)
 6713                            .into_iter()
 6714                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6715                            .collect::<Vec<_>>();
 6716                        Some(
 6717                            providers_with_identifiers
 6718                                .into_iter()
 6719                                .map(|dynamic_caps| {
 6720                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6721                                    self.request_lsp(
 6722                                        buffer.clone(),
 6723                                        LanguageServerToQuery::Other(server_id),
 6724                                        GetDocumentDiagnostics {
 6725                                            previous_result_id: result_id,
 6726                                            dynamic_caps,
 6727                                        },
 6728                                        cx,
 6729                                    )
 6730                                })
 6731                                .collect::<Vec<_>>(),
 6732                        )
 6733                    });
 6734
 6735                    result.unwrap_or_default()
 6736                })
 6737                .collect::<Vec<_>>();
 6738
 6739            cx.background_spawn(async move {
 6740                let mut responses = Vec::new();
 6741                for diagnostics in join_all(pull_diagnostics).await {
 6742                    responses.extend(diagnostics?);
 6743                }
 6744                Ok(Some(responses))
 6745            })
 6746        }
 6747    }
 6748
 6749    pub fn applicable_inlay_chunks(
 6750        &mut self,
 6751        buffer: &Entity<Buffer>,
 6752        ranges: &[Range<text::Anchor>],
 6753        cx: &mut Context<Self>,
 6754    ) -> Vec<Range<BufferRow>> {
 6755        self.latest_lsp_data(buffer, cx)
 6756            .inlay_hints
 6757            .applicable_chunks(ranges)
 6758            .map(|chunk| chunk.row_range())
 6759            .collect()
 6760    }
 6761
 6762    pub fn invalidate_inlay_hints<'a>(
 6763        &'a mut self,
 6764        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6765    ) {
 6766        for buffer_id in for_buffers {
 6767            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6768                lsp_data.inlay_hints.clear();
 6769            }
 6770        }
 6771    }
 6772
 6773    pub fn inlay_hints(
 6774        &mut self,
 6775        invalidate: InvalidationStrategy,
 6776        buffer: Entity<Buffer>,
 6777        ranges: Vec<Range<text::Anchor>>,
 6778        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6779        cx: &mut Context<Self>,
 6780    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6781        let next_hint_id = self.next_hint_id.clone();
 6782        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6783        let query_version = lsp_data.buffer_version.clone();
 6784        let mut lsp_refresh_requested = false;
 6785        let for_server = if let InvalidationStrategy::RefreshRequested {
 6786            server_id,
 6787            request_id,
 6788        } = invalidate
 6789        {
 6790            let invalidated = lsp_data
 6791                .inlay_hints
 6792                .invalidate_for_server_refresh(server_id, request_id);
 6793            lsp_refresh_requested = invalidated;
 6794            Some(server_id)
 6795        } else {
 6796            None
 6797        };
 6798        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6799        let known_chunks = known_chunks
 6800            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6801            .map(|(_, known_chunks)| known_chunks)
 6802            .unwrap_or_default();
 6803
 6804        let mut hint_fetch_tasks = Vec::new();
 6805        let mut cached_inlay_hints = None;
 6806        let mut ranges_to_query = None;
 6807        let applicable_chunks = existing_inlay_hints
 6808            .applicable_chunks(ranges.as_slice())
 6809            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6810            .collect::<Vec<_>>();
 6811        if applicable_chunks.is_empty() {
 6812            return HashMap::default();
 6813        }
 6814
 6815        for row_chunk in applicable_chunks {
 6816            match (
 6817                existing_inlay_hints
 6818                    .cached_hints(&row_chunk)
 6819                    .filter(|_| !lsp_refresh_requested)
 6820                    .cloned(),
 6821                existing_inlay_hints
 6822                    .fetched_hints(&row_chunk)
 6823                    .as_ref()
 6824                    .filter(|_| !lsp_refresh_requested)
 6825                    .cloned(),
 6826            ) {
 6827                (None, None) => {
 6828                    let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
 6829                        continue;
 6830                    };
 6831                    ranges_to_query
 6832                        .get_or_insert_with(Vec::new)
 6833                        .push((row_chunk, chunk_range));
 6834                }
 6835                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6836                (Some(cached_hints), None) => {
 6837                    for (server_id, cached_hints) in cached_hints {
 6838                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6839                            cached_inlay_hints
 6840                                .get_or_insert_with(HashMap::default)
 6841                                .entry(row_chunk.row_range())
 6842                                .or_insert_with(HashMap::default)
 6843                                .entry(server_id)
 6844                                .or_insert_with(Vec::new)
 6845                                .extend(cached_hints);
 6846                        }
 6847                    }
 6848                }
 6849                (Some(cached_hints), Some(fetched_hints)) => {
 6850                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6851                    for (server_id, cached_hints) in cached_hints {
 6852                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6853                            cached_inlay_hints
 6854                                .get_or_insert_with(HashMap::default)
 6855                                .entry(row_chunk.row_range())
 6856                                .or_insert_with(HashMap::default)
 6857                                .entry(server_id)
 6858                                .or_insert_with(Vec::new)
 6859                                .extend(cached_hints);
 6860                        }
 6861                    }
 6862                }
 6863            }
 6864        }
 6865
 6866        if hint_fetch_tasks.is_empty()
 6867            && ranges_to_query
 6868                .as_ref()
 6869                .is_none_or(|ranges| ranges.is_empty())
 6870            && let Some(cached_inlay_hints) = cached_inlay_hints
 6871        {
 6872            cached_inlay_hints
 6873                .into_iter()
 6874                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6875                .collect()
 6876        } else {
 6877            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6878                let next_hint_id = next_hint_id.clone();
 6879                let buffer = buffer.clone();
 6880                let query_version = query_version.clone();
 6881                let new_inlay_hints = cx
 6882                    .spawn(async move |lsp_store, cx| {
 6883                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6884                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6885                        })?;
 6886                        new_fetch_task
 6887                            .await
 6888                            .and_then(|new_hints_by_server| {
 6889                                lsp_store.update(cx, |lsp_store, cx| {
 6890                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6891                                    let update_cache = lsp_data.buffer_version == query_version;
 6892                                    if new_hints_by_server.is_empty() {
 6893                                        if update_cache {
 6894                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6895                                        }
 6896                                        HashMap::default()
 6897                                    } else {
 6898                                        new_hints_by_server
 6899                                            .into_iter()
 6900                                            .map(|(server_id, new_hints)| {
 6901                                                let new_hints = new_hints
 6902                                                    .into_iter()
 6903                                                    .map(|new_hint| {
 6904                                                        (
 6905                                                            InlayId::Hint(next_hint_id.fetch_add(
 6906                                                                1,
 6907                                                                atomic::Ordering::AcqRel,
 6908                                                            )),
 6909                                                            new_hint,
 6910                                                        )
 6911                                                    })
 6912                                                    .collect::<Vec<_>>();
 6913                                                if update_cache {
 6914                                                    lsp_data.inlay_hints.insert_new_hints(
 6915                                                        chunk,
 6916                                                        server_id,
 6917                                                        new_hints.clone(),
 6918                                                    );
 6919                                                }
 6920                                                (server_id, new_hints)
 6921                                            })
 6922                                            .collect()
 6923                                    }
 6924                                })
 6925                            })
 6926                            .map_err(Arc::new)
 6927                    })
 6928                    .shared();
 6929
 6930                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6931                *fetch_task = Some(new_inlay_hints.clone());
 6932                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6933            }
 6934
 6935            cached_inlay_hints
 6936                .unwrap_or_default()
 6937                .into_iter()
 6938                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6939                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6940                    (
 6941                        chunk.row_range(),
 6942                        cx.spawn(async move |_, _| {
 6943                            hints_fetch.await.map_err(|e| {
 6944                                if e.error_code() != ErrorCode::Internal {
 6945                                    anyhow!(e.error_code())
 6946                                } else {
 6947                                    anyhow!("{e:#}")
 6948                                }
 6949                            })
 6950                        }),
 6951                    )
 6952                }))
 6953                .collect()
 6954        }
 6955    }
 6956
 6957    fn fetch_inlay_hints(
 6958        &mut self,
 6959        for_server: Option<LanguageServerId>,
 6960        buffer: &Entity<Buffer>,
 6961        range: Range<Anchor>,
 6962        cx: &mut Context<Self>,
 6963    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6964        let request = InlayHints {
 6965            range: range.clone(),
 6966        };
 6967        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6968            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6969                return Task::ready(Ok(HashMap::default()));
 6970            }
 6971            let request_task = upstream_client.request_lsp(
 6972                project_id,
 6973                for_server.map(|id| id.to_proto()),
 6974                LSP_REQUEST_TIMEOUT,
 6975                cx.background_executor().clone(),
 6976                request.to_proto(project_id, buffer.read(cx)),
 6977            );
 6978            let buffer = buffer.clone();
 6979            cx.spawn(async move |weak_lsp_store, cx| {
 6980                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6981                    return Ok(HashMap::default());
 6982                };
 6983                let Some(responses) = request_task.await? else {
 6984                    return Ok(HashMap::default());
 6985                };
 6986
 6987                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6988                    let lsp_store = lsp_store.clone();
 6989                    let buffer = buffer.clone();
 6990                    let cx = cx.clone();
 6991                    let request = request.clone();
 6992                    async move {
 6993                        (
 6994                            LanguageServerId::from_proto(response.server_id),
 6995                            request
 6996                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6997                                .await,
 6998                        )
 6999                    }
 7000                }))
 7001                .await;
 7002
 7003                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7004                let mut has_errors = false;
 7005                let inlay_hints = inlay_hints
 7006                    .into_iter()
 7007                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7008                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7009                        Err(e) => {
 7010                            has_errors = true;
 7011                            log::error!("{e:#}");
 7012                            None
 7013                        }
 7014                    })
 7015                    .map(|(server_id, mut new_hints)| {
 7016                        new_hints.retain(|hint| {
 7017                            hint.position.is_valid(&buffer_snapshot)
 7018                                && range.start.is_valid(&buffer_snapshot)
 7019                                && range.end.is_valid(&buffer_snapshot)
 7020                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7021                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7022                        });
 7023                        (server_id, new_hints)
 7024                    })
 7025                    .collect::<HashMap<_, _>>();
 7026                anyhow::ensure!(
 7027                    !has_errors || !inlay_hints.is_empty(),
 7028                    "Failed to fetch inlay hints"
 7029                );
 7030                Ok(inlay_hints)
 7031            })
 7032        } else {
 7033            let inlay_hints_task = match for_server {
 7034                Some(server_id) => {
 7035                    let server_task = self.request_lsp(
 7036                        buffer.clone(),
 7037                        LanguageServerToQuery::Other(server_id),
 7038                        request,
 7039                        cx,
 7040                    );
 7041                    cx.background_spawn(async move {
 7042                        let mut responses = Vec::new();
 7043                        match server_task.await {
 7044                            Ok(response) => responses.push((server_id, response)),
 7045                            // rust-analyzer likes to error with this when its still loading up
 7046                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7047                            Err(e) => log::error!(
 7048                                "Error handling response for inlay hints request: {e:#}"
 7049                            ),
 7050                        }
 7051                        responses
 7052                    })
 7053                }
 7054                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7055            };
 7056            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7057            cx.background_spawn(async move {
 7058                Ok(inlay_hints_task
 7059                    .await
 7060                    .into_iter()
 7061                    .map(|(server_id, mut new_hints)| {
 7062                        new_hints.retain(|hint| {
 7063                            hint.position.is_valid(&buffer_snapshot)
 7064                                && range.start.is_valid(&buffer_snapshot)
 7065                                && range.end.is_valid(&buffer_snapshot)
 7066                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7067                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7068                        });
 7069                        (server_id, new_hints)
 7070                    })
 7071                    .collect())
 7072            })
 7073        }
 7074    }
 7075
 7076    pub fn pull_diagnostics_for_buffer(
 7077        &mut self,
 7078        buffer: Entity<Buffer>,
 7079        cx: &mut Context<Self>,
 7080    ) -> Task<anyhow::Result<()>> {
 7081        let diagnostics = self.pull_diagnostics(buffer, cx);
 7082        cx.spawn(async move |lsp_store, cx| {
 7083            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7084                return Ok(());
 7085            };
 7086            lsp_store.update(cx, |lsp_store, cx| {
 7087                if lsp_store.as_local().is_none() {
 7088                    return;
 7089                }
 7090
 7091                let mut unchanged_buffers = HashSet::default();
 7092                let mut changed_buffers = HashSet::default();
 7093                let server_diagnostics_updates = diagnostics
 7094                    .into_iter()
 7095                    .filter_map(|diagnostics_set| match diagnostics_set {
 7096                        LspPullDiagnostics::Response {
 7097                            server_id,
 7098                            uri,
 7099                            diagnostics,
 7100                        } => Some((server_id, uri, diagnostics)),
 7101                        LspPullDiagnostics::Default => None,
 7102                    })
 7103                    .fold(
 7104                        HashMap::default(),
 7105                        |mut acc, (server_id, uri, diagnostics)| {
 7106                            let (result_id, diagnostics) = match diagnostics {
 7107                                PulledDiagnostics::Unchanged { result_id } => {
 7108                                    unchanged_buffers.insert(uri.clone());
 7109                                    (Some(result_id), Vec::new())
 7110                                }
 7111                                PulledDiagnostics::Changed {
 7112                                    result_id,
 7113                                    diagnostics,
 7114                                } => {
 7115                                    changed_buffers.insert(uri.clone());
 7116                                    (result_id, diagnostics)
 7117                                }
 7118                            };
 7119                            let disk_based_sources = Cow::Owned(
 7120                                lsp_store
 7121                                    .language_server_adapter_for_id(server_id)
 7122                                    .as_ref()
 7123                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7124                                    .unwrap_or(&[])
 7125                                    .to_vec(),
 7126                            );
 7127                            acc.entry(server_id).or_insert_with(Vec::new).push(
 7128                                DocumentDiagnosticsUpdate {
 7129                                    server_id,
 7130                                    diagnostics: lsp::PublishDiagnosticsParams {
 7131                                        uri,
 7132                                        diagnostics,
 7133                                        version: None,
 7134                                    },
 7135                                    result_id,
 7136                                    disk_based_sources,
 7137                                },
 7138                            );
 7139                            acc
 7140                        },
 7141                    );
 7142
 7143                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7144                    lsp_store
 7145                        .merge_lsp_diagnostics(
 7146                            DiagnosticSourceKind::Pulled,
 7147                            diagnostic_updates,
 7148                            |buffer, old_diagnostic, cx| {
 7149                                File::from_dyn(buffer.file())
 7150                                    .and_then(|file| {
 7151                                        let abs_path = file.as_local()?.abs_path(cx);
 7152                                        lsp::Uri::from_file_path(abs_path).ok()
 7153                                    })
 7154                                    .is_none_or(|buffer_uri| {
 7155                                        unchanged_buffers.contains(&buffer_uri)
 7156                                            || match old_diagnostic.source_kind {
 7157                                                DiagnosticSourceKind::Pulled => {
 7158                                                    !changed_buffers.contains(&buffer_uri)
 7159                                                }
 7160                                                DiagnosticSourceKind::Other
 7161                                                | DiagnosticSourceKind::Pushed => true,
 7162                                            }
 7163                                    })
 7164                            },
 7165                            cx,
 7166                        )
 7167                        .log_err();
 7168                }
 7169            })
 7170        })
 7171    }
 7172
 7173    pub fn document_colors(
 7174        &mut self,
 7175        known_cache_version: Option<usize>,
 7176        buffer: Entity<Buffer>,
 7177        cx: &mut Context<Self>,
 7178    ) -> Option<DocumentColorTask> {
 7179        let version_queried_for = buffer.read(cx).version();
 7180        let buffer_id = buffer.read(cx).remote_id();
 7181
 7182        let current_language_servers = self.as_local().map(|local| {
 7183            local
 7184                .buffers_opened_in_servers
 7185                .get(&buffer_id)
 7186                .cloned()
 7187                .unwrap_or_default()
 7188        });
 7189
 7190        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7191            if let Some(cached_colors) = &lsp_data.document_colors {
 7192                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7193                    let has_different_servers =
 7194                        current_language_servers.is_some_and(|current_language_servers| {
 7195                            current_language_servers
 7196                                != cached_colors.colors.keys().copied().collect()
 7197                        });
 7198                    if !has_different_servers {
 7199                        let cache_version = cached_colors.cache_version;
 7200                        if Some(cache_version) == known_cache_version {
 7201                            return None;
 7202                        } else {
 7203                            return Some(
 7204                                Task::ready(Ok(DocumentColors {
 7205                                    colors: cached_colors
 7206                                        .colors
 7207                                        .values()
 7208                                        .flatten()
 7209                                        .cloned()
 7210                                        .collect(),
 7211                                    cache_version: Some(cache_version),
 7212                                }))
 7213                                .shared(),
 7214                            );
 7215                        }
 7216                    }
 7217                }
 7218            }
 7219        }
 7220
 7221        let color_lsp_data = self
 7222            .latest_lsp_data(&buffer, cx)
 7223            .document_colors
 7224            .get_or_insert_default();
 7225        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7226            && !version_queried_for.changed_since(updating_for)
 7227        {
 7228            return Some(running_update.clone());
 7229        }
 7230        let buffer_version_queried_for = version_queried_for.clone();
 7231        let new_task = cx
 7232            .spawn(async move |lsp_store, cx| {
 7233                cx.background_executor()
 7234                    .timer(Duration::from_millis(30))
 7235                    .await;
 7236                let fetched_colors = lsp_store
 7237                    .update(cx, |lsp_store, cx| {
 7238                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7239                    })?
 7240                    .await
 7241                    .context("fetching document colors")
 7242                    .map_err(Arc::new);
 7243                let fetched_colors = match fetched_colors {
 7244                    Ok(fetched_colors) => {
 7245                        if Some(true)
 7246                            == buffer
 7247                                .update(cx, |buffer, _| {
 7248                                    buffer.version() != buffer_version_queried_for
 7249                                })
 7250                                .ok()
 7251                        {
 7252                            return Ok(DocumentColors::default());
 7253                        }
 7254                        fetched_colors
 7255                    }
 7256                    Err(e) => {
 7257                        lsp_store
 7258                            .update(cx, |lsp_store, _| {
 7259                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7260                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7261                                        document_colors.colors_update = None;
 7262                                    }
 7263                                }
 7264                            })
 7265                            .ok();
 7266                        return Err(e);
 7267                    }
 7268                };
 7269
 7270                lsp_store
 7271                    .update(cx, |lsp_store, cx| {
 7272                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7273                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7274
 7275                        if let Some(fetched_colors) = fetched_colors {
 7276                            if lsp_data.buffer_version == buffer_version_queried_for {
 7277                                lsp_colors.colors.extend(fetched_colors);
 7278                                lsp_colors.cache_version += 1;
 7279                            } else if !lsp_data
 7280                                .buffer_version
 7281                                .changed_since(&buffer_version_queried_for)
 7282                            {
 7283                                lsp_data.buffer_version = buffer_version_queried_for;
 7284                                lsp_colors.colors = fetched_colors;
 7285                                lsp_colors.cache_version += 1;
 7286                            }
 7287                        }
 7288                        lsp_colors.colors_update = None;
 7289                        let colors = lsp_colors
 7290                            .colors
 7291                            .values()
 7292                            .flatten()
 7293                            .cloned()
 7294                            .collect::<HashSet<_>>();
 7295                        DocumentColors {
 7296                            colors,
 7297                            cache_version: Some(lsp_colors.cache_version),
 7298                        }
 7299                    })
 7300                    .map_err(Arc::new)
 7301            })
 7302            .shared();
 7303        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7304        Some(new_task)
 7305    }
 7306
 7307    fn fetch_document_colors_for_buffer(
 7308        &mut self,
 7309        buffer: &Entity<Buffer>,
 7310        cx: &mut Context<Self>,
 7311    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7312        if let Some((client, project_id)) = self.upstream_client() {
 7313            let request = GetDocumentColor {};
 7314            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7315                return Task::ready(Ok(None));
 7316            }
 7317
 7318            let request_task = client.request_lsp(
 7319                project_id,
 7320                None,
 7321                LSP_REQUEST_TIMEOUT,
 7322                cx.background_executor().clone(),
 7323                request.to_proto(project_id, buffer.read(cx)),
 7324            );
 7325            let buffer = buffer.clone();
 7326            cx.spawn(async move |lsp_store, cx| {
 7327                let Some(lsp_store) = lsp_store.upgrade() else {
 7328                    return Ok(None);
 7329                };
 7330                let colors = join_all(
 7331                    request_task
 7332                        .await
 7333                        .log_err()
 7334                        .flatten()
 7335                        .map(|response| response.payload)
 7336                        .unwrap_or_default()
 7337                        .into_iter()
 7338                        .map(|color_response| {
 7339                            let response = request.response_from_proto(
 7340                                color_response.response,
 7341                                lsp_store.clone(),
 7342                                buffer.clone(),
 7343                                cx.clone(),
 7344                            );
 7345                            async move {
 7346                                (
 7347                                    LanguageServerId::from_proto(color_response.server_id),
 7348                                    response.await.log_err().unwrap_or_default(),
 7349                                )
 7350                            }
 7351                        }),
 7352                )
 7353                .await
 7354                .into_iter()
 7355                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7356                    acc.entry(server_id)
 7357                        .or_insert_with(HashSet::default)
 7358                        .extend(colors);
 7359                    acc
 7360                });
 7361                Ok(Some(colors))
 7362            })
 7363        } else {
 7364            let document_colors_task =
 7365                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7366            cx.background_spawn(async move {
 7367                Ok(Some(
 7368                    document_colors_task
 7369                        .await
 7370                        .into_iter()
 7371                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7372                            acc.entry(server_id)
 7373                                .or_insert_with(HashSet::default)
 7374                                .extend(colors);
 7375                            acc
 7376                        })
 7377                        .into_iter()
 7378                        .collect(),
 7379                ))
 7380            })
 7381        }
 7382    }
 7383
 7384    pub fn signature_help<T: ToPointUtf16>(
 7385        &mut self,
 7386        buffer: &Entity<Buffer>,
 7387        position: T,
 7388        cx: &mut Context<Self>,
 7389    ) -> Task<Option<Vec<SignatureHelp>>> {
 7390        let position = position.to_point_utf16(buffer.read(cx));
 7391
 7392        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7393            let request = GetSignatureHelp { position };
 7394            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7395                return Task::ready(None);
 7396            }
 7397            let request_task = client.request_lsp(
 7398                upstream_project_id,
 7399                None,
 7400                LSP_REQUEST_TIMEOUT,
 7401                cx.background_executor().clone(),
 7402                request.to_proto(upstream_project_id, buffer.read(cx)),
 7403            );
 7404            let buffer = buffer.clone();
 7405            cx.spawn(async move |weak_lsp_store, cx| {
 7406                let lsp_store = weak_lsp_store.upgrade()?;
 7407                let signatures = join_all(
 7408                    request_task
 7409                        .await
 7410                        .log_err()
 7411                        .flatten()
 7412                        .map(|response| response.payload)
 7413                        .unwrap_or_default()
 7414                        .into_iter()
 7415                        .map(|response| {
 7416                            let response = GetSignatureHelp { position }.response_from_proto(
 7417                                response.response,
 7418                                lsp_store.clone(),
 7419                                buffer.clone(),
 7420                                cx.clone(),
 7421                            );
 7422                            async move { response.await.log_err().flatten() }
 7423                        }),
 7424                )
 7425                .await
 7426                .into_iter()
 7427                .flatten()
 7428                .collect();
 7429                Some(signatures)
 7430            })
 7431        } else {
 7432            let all_actions_task = self.request_multiple_lsp_locally(
 7433                buffer,
 7434                Some(position),
 7435                GetSignatureHelp { position },
 7436                cx,
 7437            );
 7438            cx.background_spawn(async move {
 7439                Some(
 7440                    all_actions_task
 7441                        .await
 7442                        .into_iter()
 7443                        .flat_map(|(_, actions)| actions)
 7444                        .collect::<Vec<_>>(),
 7445                )
 7446            })
 7447        }
 7448    }
 7449
 7450    pub fn hover(
 7451        &mut self,
 7452        buffer: &Entity<Buffer>,
 7453        position: PointUtf16,
 7454        cx: &mut Context<Self>,
 7455    ) -> Task<Option<Vec<Hover>>> {
 7456        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7457            let request = GetHover { position };
 7458            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7459                return Task::ready(None);
 7460            }
 7461            let request_task = client.request_lsp(
 7462                upstream_project_id,
 7463                None,
 7464                LSP_REQUEST_TIMEOUT,
 7465                cx.background_executor().clone(),
 7466                request.to_proto(upstream_project_id, buffer.read(cx)),
 7467            );
 7468            let buffer = buffer.clone();
 7469            cx.spawn(async move |weak_lsp_store, cx| {
 7470                let lsp_store = weak_lsp_store.upgrade()?;
 7471                let hovers = join_all(
 7472                    request_task
 7473                        .await
 7474                        .log_err()
 7475                        .flatten()
 7476                        .map(|response| response.payload)
 7477                        .unwrap_or_default()
 7478                        .into_iter()
 7479                        .map(|response| {
 7480                            let response = GetHover { position }.response_from_proto(
 7481                                response.response,
 7482                                lsp_store.clone(),
 7483                                buffer.clone(),
 7484                                cx.clone(),
 7485                            );
 7486                            async move {
 7487                                response
 7488                                    .await
 7489                                    .log_err()
 7490                                    .flatten()
 7491                                    .and_then(remove_empty_hover_blocks)
 7492                            }
 7493                        }),
 7494                )
 7495                .await
 7496                .into_iter()
 7497                .flatten()
 7498                .collect();
 7499                Some(hovers)
 7500            })
 7501        } else {
 7502            let all_actions_task = self.request_multiple_lsp_locally(
 7503                buffer,
 7504                Some(position),
 7505                GetHover { position },
 7506                cx,
 7507            );
 7508            cx.background_spawn(async move {
 7509                Some(
 7510                    all_actions_task
 7511                        .await
 7512                        .into_iter()
 7513                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7514                        .collect::<Vec<Hover>>(),
 7515                )
 7516            })
 7517        }
 7518    }
 7519
 7520    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7521        let language_registry = self.languages.clone();
 7522
 7523        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7524            let request = upstream_client.request(proto::GetProjectSymbols {
 7525                project_id: *project_id,
 7526                query: query.to_string(),
 7527            });
 7528            cx.foreground_executor().spawn(async move {
 7529                let response = request.await?;
 7530                let mut symbols = Vec::new();
 7531                let core_symbols = response
 7532                    .symbols
 7533                    .into_iter()
 7534                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7535                    .collect::<Vec<_>>();
 7536                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7537                    .await;
 7538                Ok(symbols)
 7539            })
 7540        } else if let Some(local) = self.as_local() {
 7541            struct WorkspaceSymbolsResult {
 7542                server_id: LanguageServerId,
 7543                lsp_adapter: Arc<CachedLspAdapter>,
 7544                worktree: WeakEntity<Worktree>,
 7545                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7546            }
 7547
 7548            let mut requests = Vec::new();
 7549            let mut requested_servers = BTreeSet::new();
 7550            for (seed, state) in local.language_server_ids.iter() {
 7551                let Some(worktree_handle) = self
 7552                    .worktree_store
 7553                    .read(cx)
 7554                    .worktree_for_id(seed.worktree_id, cx)
 7555                else {
 7556                    continue;
 7557                };
 7558                let worktree = worktree_handle.read(cx);
 7559                if !worktree.is_visible() {
 7560                    continue;
 7561                }
 7562
 7563                if !requested_servers.insert(state.id) {
 7564                    continue;
 7565                }
 7566
 7567                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7568                    Some(LanguageServerState::Running {
 7569                        adapter, server, ..
 7570                    }) => (adapter.clone(), server),
 7571
 7572                    _ => continue,
 7573                };
 7574                let supports_workspace_symbol_request =
 7575                    match server.capabilities().workspace_symbol_provider {
 7576                        Some(OneOf::Left(supported)) => supported,
 7577                        Some(OneOf::Right(_)) => true,
 7578                        None => false,
 7579                    };
 7580                if !supports_workspace_symbol_request {
 7581                    continue;
 7582                }
 7583                let worktree_handle = worktree_handle.clone();
 7584                let server_id = server.server_id();
 7585                requests.push(
 7586                        server
 7587                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7588                                lsp::WorkspaceSymbolParams {
 7589                                    query: query.to_string(),
 7590                                    ..Default::default()
 7591                                },
 7592                            )
 7593                            .map(move |response| {
 7594                                let lsp_symbols = response.into_response()
 7595                                    .context("workspace symbols request")
 7596                                    .log_err()
 7597                                    .flatten()
 7598                                    .map(|symbol_response| match symbol_response {
 7599                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7600                                            flat_responses.into_iter().map(|lsp_symbol| {
 7601                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7602                                            }).collect::<Vec<_>>()
 7603                                        }
 7604                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7605                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7606                                                let location = match lsp_symbol.location {
 7607                                                    OneOf::Left(location) => location,
 7608                                                    OneOf::Right(_) => {
 7609                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7610                                                        return None
 7611                                                    }
 7612                                                };
 7613                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7614                                            }).collect::<Vec<_>>()
 7615                                        }
 7616                                    }).unwrap_or_default();
 7617
 7618                                WorkspaceSymbolsResult {
 7619                                    server_id,
 7620                                    lsp_adapter,
 7621                                    worktree: worktree_handle.downgrade(),
 7622                                    lsp_symbols,
 7623                                }
 7624                            }),
 7625                    );
 7626            }
 7627
 7628            cx.spawn(async move |this, cx| {
 7629                let responses = futures::future::join_all(requests).await;
 7630                let this = match this.upgrade() {
 7631                    Some(this) => this,
 7632                    None => return Ok(Vec::new()),
 7633                };
 7634
 7635                let mut symbols = Vec::new();
 7636                for result in responses {
 7637                    let core_symbols = this.update(cx, |this, cx| {
 7638                        result
 7639                            .lsp_symbols
 7640                            .into_iter()
 7641                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7642                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7643                                let source_worktree = result.worktree.upgrade()?;
 7644                                let source_worktree_id = source_worktree.read(cx).id();
 7645
 7646                                let path = if let Some((tree, rel_path)) =
 7647                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7648                                {
 7649                                    let worktree_id = tree.read(cx).id();
 7650                                    SymbolLocation::InProject(ProjectPath {
 7651                                        worktree_id,
 7652                                        path: rel_path,
 7653                                    })
 7654                                } else {
 7655                                    SymbolLocation::OutsideProject {
 7656                                        signature: this.symbol_signature(&abs_path),
 7657                                        abs_path: abs_path.into(),
 7658                                    }
 7659                                };
 7660
 7661                                Some(CoreSymbol {
 7662                                    source_language_server_id: result.server_id,
 7663                                    language_server_name: result.lsp_adapter.name.clone(),
 7664                                    source_worktree_id,
 7665                                    path,
 7666                                    kind: symbol_kind,
 7667                                    name: symbol_name,
 7668                                    range: range_from_lsp(symbol_location.range),
 7669                                })
 7670                            })
 7671                            .collect()
 7672                    })?;
 7673
 7674                    populate_labels_for_symbols(
 7675                        core_symbols,
 7676                        &language_registry,
 7677                        Some(result.lsp_adapter),
 7678                        &mut symbols,
 7679                    )
 7680                    .await;
 7681                }
 7682
 7683                Ok(symbols)
 7684            })
 7685        } else {
 7686            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7687        }
 7688    }
 7689
 7690    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7691        let mut summary = DiagnosticSummary::default();
 7692        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7693            summary.error_count += path_summary.error_count;
 7694            summary.warning_count += path_summary.warning_count;
 7695        }
 7696        summary
 7697    }
 7698
 7699    /// Returns the diagnostic summary for a specific project path.
 7700    pub fn diagnostic_summary_for_path(
 7701        &self,
 7702        project_path: &ProjectPath,
 7703        _: &App,
 7704    ) -> DiagnosticSummary {
 7705        if let Some(summaries) = self
 7706            .diagnostic_summaries
 7707            .get(&project_path.worktree_id)
 7708            .and_then(|map| map.get(&project_path.path))
 7709        {
 7710            let (error_count, warning_count) = summaries.iter().fold(
 7711                (0, 0),
 7712                |(error_count, warning_count), (_language_server_id, summary)| {
 7713                    (
 7714                        error_count + summary.error_count,
 7715                        warning_count + summary.warning_count,
 7716                    )
 7717                },
 7718            );
 7719
 7720            DiagnosticSummary {
 7721                error_count,
 7722                warning_count,
 7723            }
 7724        } else {
 7725            DiagnosticSummary::default()
 7726        }
 7727    }
 7728
 7729    pub fn diagnostic_summaries<'a>(
 7730        &'a self,
 7731        include_ignored: bool,
 7732        cx: &'a App,
 7733    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7734        self.worktree_store
 7735            .read(cx)
 7736            .visible_worktrees(cx)
 7737            .filter_map(|worktree| {
 7738                let worktree = worktree.read(cx);
 7739                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7740            })
 7741            .flat_map(move |(worktree, summaries)| {
 7742                let worktree_id = worktree.id();
 7743                summaries
 7744                    .iter()
 7745                    .filter(move |(path, _)| {
 7746                        include_ignored
 7747                            || worktree
 7748                                .entry_for_path(path.as_ref())
 7749                                .is_some_and(|entry| !entry.is_ignored)
 7750                    })
 7751                    .flat_map(move |(path, summaries)| {
 7752                        summaries.iter().map(move |(server_id, summary)| {
 7753                            (
 7754                                ProjectPath {
 7755                                    worktree_id,
 7756                                    path: path.clone(),
 7757                                },
 7758                                *server_id,
 7759                                *summary,
 7760                            )
 7761                        })
 7762                    })
 7763            })
 7764    }
 7765
 7766    pub fn on_buffer_edited(
 7767        &mut self,
 7768        buffer: Entity<Buffer>,
 7769        cx: &mut Context<Self>,
 7770    ) -> Option<()> {
 7771        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7772            Some(
 7773                self.as_local()?
 7774                    .language_servers_for_buffer(buffer, cx)
 7775                    .map(|i| i.1.clone())
 7776                    .collect(),
 7777            )
 7778        })?;
 7779
 7780        let buffer = buffer.read(cx);
 7781        let file = File::from_dyn(buffer.file())?;
 7782        let abs_path = file.as_local()?.abs_path(cx);
 7783        let uri = lsp::Uri::from_file_path(&abs_path)
 7784            .ok()
 7785            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7786            .log_err()?;
 7787        let next_snapshot = buffer.text_snapshot();
 7788        for language_server in language_servers {
 7789            let language_server = language_server.clone();
 7790
 7791            let buffer_snapshots = self
 7792                .as_local_mut()?
 7793                .buffer_snapshots
 7794                .get_mut(&buffer.remote_id())
 7795                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7796            let previous_snapshot = buffer_snapshots.last()?;
 7797
 7798            let build_incremental_change = || {
 7799                buffer
 7800                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7801                        previous_snapshot.snapshot.version(),
 7802                    )
 7803                    .map(|edit| {
 7804                        let edit_start = edit.new.start.0;
 7805                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7806                        let new_text = next_snapshot
 7807                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7808                            .collect();
 7809                        lsp::TextDocumentContentChangeEvent {
 7810                            range: Some(lsp::Range::new(
 7811                                point_to_lsp(edit_start),
 7812                                point_to_lsp(edit_end),
 7813                            )),
 7814                            range_length: None,
 7815                            text: new_text,
 7816                        }
 7817                    })
 7818                    .collect()
 7819            };
 7820
 7821            let document_sync_kind = language_server
 7822                .capabilities()
 7823                .text_document_sync
 7824                .as_ref()
 7825                .and_then(|sync| match sync {
 7826                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7827                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7828                });
 7829
 7830            let content_changes: Vec<_> = match document_sync_kind {
 7831                Some(lsp::TextDocumentSyncKind::FULL) => {
 7832                    vec![lsp::TextDocumentContentChangeEvent {
 7833                        range: None,
 7834                        range_length: None,
 7835                        text: next_snapshot.text(),
 7836                    }]
 7837                }
 7838                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7839                _ => {
 7840                    #[cfg(any(test, feature = "test-support"))]
 7841                    {
 7842                        build_incremental_change()
 7843                    }
 7844
 7845                    #[cfg(not(any(test, feature = "test-support")))]
 7846                    {
 7847                        continue;
 7848                    }
 7849                }
 7850            };
 7851
 7852            let next_version = previous_snapshot.version + 1;
 7853            buffer_snapshots.push(LspBufferSnapshot {
 7854                version: next_version,
 7855                snapshot: next_snapshot.clone(),
 7856            });
 7857
 7858            language_server
 7859                .notify::<lsp::notification::DidChangeTextDocument>(
 7860                    lsp::DidChangeTextDocumentParams {
 7861                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7862                            uri.clone(),
 7863                            next_version,
 7864                        ),
 7865                        content_changes,
 7866                    },
 7867                )
 7868                .ok();
 7869            self.pull_workspace_diagnostics(language_server.server_id());
 7870        }
 7871
 7872        None
 7873    }
 7874
 7875    pub fn on_buffer_saved(
 7876        &mut self,
 7877        buffer: Entity<Buffer>,
 7878        cx: &mut Context<Self>,
 7879    ) -> Option<()> {
 7880        let file = File::from_dyn(buffer.read(cx).file())?;
 7881        let worktree_id = file.worktree_id(cx);
 7882        let abs_path = file.as_local()?.abs_path(cx);
 7883        let text_document = lsp::TextDocumentIdentifier {
 7884            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7885        };
 7886        let local = self.as_local()?;
 7887
 7888        for server in local.language_servers_for_worktree(worktree_id) {
 7889            if let Some(include_text) = include_text(server.as_ref()) {
 7890                let text = if include_text {
 7891                    Some(buffer.read(cx).text())
 7892                } else {
 7893                    None
 7894                };
 7895                server
 7896                    .notify::<lsp::notification::DidSaveTextDocument>(
 7897                        lsp::DidSaveTextDocumentParams {
 7898                            text_document: text_document.clone(),
 7899                            text,
 7900                        },
 7901                    )
 7902                    .ok();
 7903            }
 7904        }
 7905
 7906        let language_servers = buffer.update(cx, |buffer, cx| {
 7907            local.language_server_ids_for_buffer(buffer, cx)
 7908        });
 7909        for language_server_id in language_servers {
 7910            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7911        }
 7912
 7913        None
 7914    }
 7915
 7916    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7917        maybe!(async move {
 7918            let mut refreshed_servers = HashSet::default();
 7919            let servers = lsp_store
 7920                .update(cx, |lsp_store, cx| {
 7921                    let local = lsp_store.as_local()?;
 7922
 7923                    let servers = local
 7924                        .language_server_ids
 7925                        .iter()
 7926                        .filter_map(|(seed, state)| {
 7927                            let worktree = lsp_store
 7928                                .worktree_store
 7929                                .read(cx)
 7930                                .worktree_for_id(seed.worktree_id, cx);
 7931                            let delegate: Arc<dyn LspAdapterDelegate> =
 7932                                worktree.map(|worktree| {
 7933                                    LocalLspAdapterDelegate::new(
 7934                                        local.languages.clone(),
 7935                                        &local.environment,
 7936                                        cx.weak_entity(),
 7937                                        &worktree,
 7938                                        local.http_client.clone(),
 7939                                        local.fs.clone(),
 7940                                        cx,
 7941                                    )
 7942                                })?;
 7943                            let server_id = state.id;
 7944
 7945                            let states = local.language_servers.get(&server_id)?;
 7946
 7947                            match states {
 7948                                LanguageServerState::Starting { .. } => None,
 7949                                LanguageServerState::Running {
 7950                                    adapter, server, ..
 7951                                } => {
 7952                                    let adapter = adapter.clone();
 7953                                    let server = server.clone();
 7954                                    refreshed_servers.insert(server.name());
 7955                                    let toolchain = seed.toolchain.clone();
 7956                                    Some(cx.spawn(async move |_, cx| {
 7957                                        let settings =
 7958                                            LocalLspStore::workspace_configuration_for_adapter(
 7959                                                adapter.adapter.clone(),
 7960                                                &delegate,
 7961                                                toolchain,
 7962                                                cx,
 7963                                            )
 7964                                            .await
 7965                                            .ok()?;
 7966                                        server
 7967                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7968                                                lsp::DidChangeConfigurationParams { settings },
 7969                                            )
 7970                                            .ok()?;
 7971                                        Some(())
 7972                                    }))
 7973                                }
 7974                            }
 7975                        })
 7976                        .collect::<Vec<_>>();
 7977
 7978                    Some(servers)
 7979                })
 7980                .ok()
 7981                .flatten()?;
 7982
 7983            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7984            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7985            // to stop and unregister its language server wrapper.
 7986            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7987            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7988            let _: Vec<Option<()>> = join_all(servers).await;
 7989
 7990            Some(())
 7991        })
 7992        .await;
 7993    }
 7994
 7995    fn maintain_workspace_config(
 7996        external_refresh_requests: watch::Receiver<()>,
 7997        cx: &mut Context<Self>,
 7998    ) -> Task<Result<()>> {
 7999        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8000        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8001
 8002        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8003            *settings_changed_tx.borrow_mut() = ();
 8004        });
 8005
 8006        let mut joint_future =
 8007            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8008        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8009        // - 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).
 8010        // - 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.
 8011        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8012        // - 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,
 8013        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8014        cx.spawn(async move |this, cx| {
 8015            while let Some(()) = joint_future.next().await {
 8016                this.update(cx, |this, cx| {
 8017                    this.refresh_server_tree(cx);
 8018                })
 8019                .ok();
 8020
 8021                Self::refresh_workspace_configurations(&this, cx).await;
 8022            }
 8023
 8024            drop(settings_observation);
 8025            anyhow::Ok(())
 8026        })
 8027    }
 8028
 8029    pub fn language_servers_for_local_buffer<'a>(
 8030        &'a self,
 8031        buffer: &Buffer,
 8032        cx: &mut App,
 8033    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8034        let local = self.as_local();
 8035        let language_server_ids = local
 8036            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8037            .unwrap_or_default();
 8038
 8039        language_server_ids
 8040            .into_iter()
 8041            .filter_map(
 8042                move |server_id| match local?.language_servers.get(&server_id)? {
 8043                    LanguageServerState::Running {
 8044                        adapter, server, ..
 8045                    } => Some((adapter, server)),
 8046                    _ => None,
 8047                },
 8048            )
 8049    }
 8050
 8051    pub fn language_server_for_local_buffer<'a>(
 8052        &'a self,
 8053        buffer: &'a Buffer,
 8054        server_id: LanguageServerId,
 8055        cx: &'a mut App,
 8056    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8057        self.as_local()?
 8058            .language_servers_for_buffer(buffer, cx)
 8059            .find(|(_, s)| s.server_id() == server_id)
 8060    }
 8061
 8062    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8063        self.diagnostic_summaries.remove(&id_to_remove);
 8064        if let Some(local) = self.as_local_mut() {
 8065            let to_remove = local.remove_worktree(id_to_remove, cx);
 8066            for server in to_remove {
 8067                self.language_server_statuses.remove(&server);
 8068            }
 8069        }
 8070    }
 8071
 8072    pub fn shared(
 8073        &mut self,
 8074        project_id: u64,
 8075        downstream_client: AnyProtoClient,
 8076        _: &mut Context<Self>,
 8077    ) {
 8078        self.downstream_client = Some((downstream_client.clone(), project_id));
 8079
 8080        for (server_id, status) in &self.language_server_statuses {
 8081            if let Some(server) = self.language_server_for_id(*server_id) {
 8082                downstream_client
 8083                    .send(proto::StartLanguageServer {
 8084                        project_id,
 8085                        server: Some(proto::LanguageServer {
 8086                            id: server_id.to_proto(),
 8087                            name: status.name.to_string(),
 8088                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8089                        }),
 8090                        capabilities: serde_json::to_string(&server.capabilities())
 8091                            .expect("serializing server LSP capabilities"),
 8092                    })
 8093                    .log_err();
 8094            }
 8095        }
 8096    }
 8097
 8098    pub fn disconnected_from_host(&mut self) {
 8099        self.downstream_client.take();
 8100    }
 8101
 8102    pub fn disconnected_from_ssh_remote(&mut self) {
 8103        if let LspStoreMode::Remote(RemoteLspStore {
 8104            upstream_client, ..
 8105        }) = &mut self.mode
 8106        {
 8107            upstream_client.take();
 8108        }
 8109    }
 8110
 8111    pub(crate) fn set_language_server_statuses_from_proto(
 8112        &mut self,
 8113        project: WeakEntity<Project>,
 8114        language_servers: Vec<proto::LanguageServer>,
 8115        server_capabilities: Vec<String>,
 8116        cx: &mut Context<Self>,
 8117    ) {
 8118        let lsp_logs = cx
 8119            .try_global::<GlobalLogStore>()
 8120            .map(|lsp_store| lsp_store.0.clone());
 8121
 8122        self.language_server_statuses = language_servers
 8123            .into_iter()
 8124            .zip(server_capabilities)
 8125            .map(|(server, server_capabilities)| {
 8126                let server_id = LanguageServerId(server.id as usize);
 8127                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8128                    self.lsp_server_capabilities
 8129                        .insert(server_id, server_capabilities);
 8130                }
 8131
 8132                let name = LanguageServerName::from_proto(server.name);
 8133                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8134
 8135                if let Some(lsp_logs) = &lsp_logs {
 8136                    lsp_logs.update(cx, |lsp_logs, cx| {
 8137                        lsp_logs.add_language_server(
 8138                            // Only remote clients get their language servers set from proto
 8139                            LanguageServerKind::Remote {
 8140                                project: project.clone(),
 8141                            },
 8142                            server_id,
 8143                            Some(name.clone()),
 8144                            worktree,
 8145                            None,
 8146                            cx,
 8147                        );
 8148                    });
 8149                }
 8150
 8151                (
 8152                    server_id,
 8153                    LanguageServerStatus {
 8154                        name,
 8155                        pending_work: Default::default(),
 8156                        has_pending_diagnostic_updates: false,
 8157                        progress_tokens: Default::default(),
 8158                        worktree,
 8159                        binary: None,
 8160                        configuration: None,
 8161                        workspace_folders: BTreeSet::new(),
 8162                    },
 8163                )
 8164            })
 8165            .collect();
 8166    }
 8167
 8168    #[cfg(test)]
 8169    pub fn update_diagnostic_entries(
 8170        &mut self,
 8171        server_id: LanguageServerId,
 8172        abs_path: PathBuf,
 8173        result_id: Option<String>,
 8174        version: Option<i32>,
 8175        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8176        cx: &mut Context<Self>,
 8177    ) -> anyhow::Result<()> {
 8178        self.merge_diagnostic_entries(
 8179            vec![DocumentDiagnosticsUpdate {
 8180                diagnostics: DocumentDiagnostics {
 8181                    diagnostics,
 8182                    document_abs_path: abs_path,
 8183                    version,
 8184                },
 8185                result_id,
 8186                server_id,
 8187                disk_based_sources: Cow::Borrowed(&[]),
 8188            }],
 8189            |_, _, _| false,
 8190            cx,
 8191        )?;
 8192        Ok(())
 8193    }
 8194
 8195    pub fn merge_diagnostic_entries<'a>(
 8196        &mut self,
 8197        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8198        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8199        cx: &mut Context<Self>,
 8200    ) -> anyhow::Result<()> {
 8201        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8202        let mut updated_diagnostics_paths = HashMap::default();
 8203        for mut update in diagnostic_updates {
 8204            let abs_path = &update.diagnostics.document_abs_path;
 8205            let server_id = update.server_id;
 8206            let Some((worktree, relative_path)) =
 8207                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8208            else {
 8209                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8210                return Ok(());
 8211            };
 8212
 8213            let worktree_id = worktree.read(cx).id();
 8214            let project_path = ProjectPath {
 8215                worktree_id,
 8216                path: relative_path,
 8217            };
 8218
 8219            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8220                let snapshot = buffer_handle.read(cx).snapshot();
 8221                let buffer = buffer_handle.read(cx);
 8222                let reused_diagnostics = buffer
 8223                    .buffer_diagnostics(Some(server_id))
 8224                    .iter()
 8225                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8226                    .map(|v| {
 8227                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8228                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8229                        DiagnosticEntry {
 8230                            range: start..end,
 8231                            diagnostic: v.diagnostic.clone(),
 8232                        }
 8233                    })
 8234                    .collect::<Vec<_>>();
 8235
 8236                self.as_local_mut()
 8237                    .context("cannot merge diagnostics on a remote LspStore")?
 8238                    .update_buffer_diagnostics(
 8239                        &buffer_handle,
 8240                        server_id,
 8241                        update.result_id,
 8242                        update.diagnostics.version,
 8243                        update.diagnostics.diagnostics.clone(),
 8244                        reused_diagnostics.clone(),
 8245                        cx,
 8246                    )?;
 8247
 8248                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8249            }
 8250
 8251            let updated = worktree.update(cx, |worktree, cx| {
 8252                self.update_worktree_diagnostics(
 8253                    worktree.id(),
 8254                    server_id,
 8255                    project_path.path.clone(),
 8256                    update.diagnostics.diagnostics,
 8257                    cx,
 8258                )
 8259            })?;
 8260            match updated {
 8261                ControlFlow::Continue(new_summary) => {
 8262                    if let Some((project_id, new_summary)) = new_summary {
 8263                        match &mut diagnostics_summary {
 8264                            Some(diagnostics_summary) => {
 8265                                diagnostics_summary
 8266                                    .more_summaries
 8267                                    .push(proto::DiagnosticSummary {
 8268                                        path: project_path.path.as_ref().to_proto(),
 8269                                        language_server_id: server_id.0 as u64,
 8270                                        error_count: new_summary.error_count,
 8271                                        warning_count: new_summary.warning_count,
 8272                                    })
 8273                            }
 8274                            None => {
 8275                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8276                                    project_id,
 8277                                    worktree_id: worktree_id.to_proto(),
 8278                                    summary: Some(proto::DiagnosticSummary {
 8279                                        path: project_path.path.as_ref().to_proto(),
 8280                                        language_server_id: server_id.0 as u64,
 8281                                        error_count: new_summary.error_count,
 8282                                        warning_count: new_summary.warning_count,
 8283                                    }),
 8284                                    more_summaries: Vec::new(),
 8285                                })
 8286                            }
 8287                        }
 8288                    }
 8289                    updated_diagnostics_paths
 8290                        .entry(server_id)
 8291                        .or_insert_with(Vec::new)
 8292                        .push(project_path);
 8293                }
 8294                ControlFlow::Break(()) => {}
 8295            }
 8296        }
 8297
 8298        if let Some((diagnostics_summary, (downstream_client, _))) =
 8299            diagnostics_summary.zip(self.downstream_client.as_ref())
 8300        {
 8301            downstream_client.send(diagnostics_summary).log_err();
 8302        }
 8303        for (server_id, paths) in updated_diagnostics_paths {
 8304            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8305        }
 8306        Ok(())
 8307    }
 8308
 8309    fn update_worktree_diagnostics(
 8310        &mut self,
 8311        worktree_id: WorktreeId,
 8312        server_id: LanguageServerId,
 8313        path_in_worktree: Arc<RelPath>,
 8314        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8315        _: &mut Context<Worktree>,
 8316    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8317        let local = match &mut self.mode {
 8318            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8319            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8320        };
 8321
 8322        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8323        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8324        let summaries_by_server_id = summaries_for_tree
 8325            .entry(path_in_worktree.clone())
 8326            .or_default();
 8327
 8328        let old_summary = summaries_by_server_id
 8329            .remove(&server_id)
 8330            .unwrap_or_default();
 8331
 8332        let new_summary = DiagnosticSummary::new(&diagnostics);
 8333        if new_summary.is_empty() {
 8334            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8335            {
 8336                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8337                    diagnostics_by_server_id.remove(ix);
 8338                }
 8339                if diagnostics_by_server_id.is_empty() {
 8340                    diagnostics_for_tree.remove(&path_in_worktree);
 8341                }
 8342            }
 8343        } else {
 8344            summaries_by_server_id.insert(server_id, new_summary);
 8345            let diagnostics_by_server_id = diagnostics_for_tree
 8346                .entry(path_in_worktree.clone())
 8347                .or_default();
 8348            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8349                Ok(ix) => {
 8350                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8351                }
 8352                Err(ix) => {
 8353                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8354                }
 8355            }
 8356        }
 8357
 8358        if !old_summary.is_empty() || !new_summary.is_empty() {
 8359            if let Some((_, project_id)) = &self.downstream_client {
 8360                Ok(ControlFlow::Continue(Some((
 8361                    *project_id,
 8362                    proto::DiagnosticSummary {
 8363                        path: path_in_worktree.to_proto(),
 8364                        language_server_id: server_id.0 as u64,
 8365                        error_count: new_summary.error_count as u32,
 8366                        warning_count: new_summary.warning_count as u32,
 8367                    },
 8368                ))))
 8369            } else {
 8370                Ok(ControlFlow::Continue(None))
 8371            }
 8372        } else {
 8373            Ok(ControlFlow::Break(()))
 8374        }
 8375    }
 8376
 8377    pub fn open_buffer_for_symbol(
 8378        &mut self,
 8379        symbol: &Symbol,
 8380        cx: &mut Context<Self>,
 8381    ) -> Task<Result<Entity<Buffer>>> {
 8382        if let Some((client, project_id)) = self.upstream_client() {
 8383            let request = client.request(proto::OpenBufferForSymbol {
 8384                project_id,
 8385                symbol: Some(Self::serialize_symbol(symbol)),
 8386            });
 8387            cx.spawn(async move |this, cx| {
 8388                let response = request.await?;
 8389                let buffer_id = BufferId::new(response.buffer_id)?;
 8390                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8391                    .await
 8392            })
 8393        } else if let Some(local) = self.as_local() {
 8394            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8395                seed.worktree_id == symbol.source_worktree_id
 8396                    && state.id == symbol.source_language_server_id
 8397                    && symbol.language_server_name == seed.name
 8398            });
 8399            if !is_valid {
 8400                return Task::ready(Err(anyhow!(
 8401                    "language server for worktree and language not found"
 8402                )));
 8403            };
 8404
 8405            let symbol_abs_path = match &symbol.path {
 8406                SymbolLocation::InProject(project_path) => self
 8407                    .worktree_store
 8408                    .read(cx)
 8409                    .absolutize(&project_path, cx)
 8410                    .context("no such worktree"),
 8411                SymbolLocation::OutsideProject {
 8412                    abs_path,
 8413                    signature: _,
 8414                } => Ok(abs_path.to_path_buf()),
 8415            };
 8416            let symbol_abs_path = match symbol_abs_path {
 8417                Ok(abs_path) => abs_path,
 8418                Err(err) => return Task::ready(Err(err)),
 8419            };
 8420            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8421                uri
 8422            } else {
 8423                return Task::ready(Err(anyhow!("invalid symbol path")));
 8424            };
 8425
 8426            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8427        } else {
 8428            Task::ready(Err(anyhow!("no upstream client or local store")))
 8429        }
 8430    }
 8431
 8432    pub(crate) fn open_local_buffer_via_lsp(
 8433        &mut self,
 8434        abs_path: lsp::Uri,
 8435        language_server_id: LanguageServerId,
 8436        cx: &mut Context<Self>,
 8437    ) -> Task<Result<Entity<Buffer>>> {
 8438        cx.spawn(async move |lsp_store, cx| {
 8439            // Escape percent-encoded string.
 8440            let current_scheme = abs_path.scheme().to_owned();
 8441            // Uri is immutable, so we can't modify the scheme
 8442
 8443            let abs_path = abs_path
 8444                .to_file_path()
 8445                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8446            let p = abs_path.clone();
 8447            let yarn_worktree = lsp_store
 8448                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8449                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8450                        cx.spawn(async move |this, cx| {
 8451                            let t = this
 8452                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8453                                .ok()?;
 8454                            t.await
 8455                        })
 8456                    }),
 8457                    None => Task::ready(None),
 8458                })?
 8459                .await;
 8460            let (worktree_root_target, known_relative_path) =
 8461                if let Some((zip_root, relative_path)) = yarn_worktree {
 8462                    (zip_root, Some(relative_path))
 8463                } else {
 8464                    (Arc::<Path>::from(abs_path.as_path()), None)
 8465                };
 8466            let (worktree, relative_path) = if let Some(result) =
 8467                lsp_store.update(cx, |lsp_store, cx| {
 8468                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8469                        worktree_store.find_worktree(&worktree_root_target, cx)
 8470                    })
 8471                })? {
 8472                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8473                (result.0, relative_path)
 8474            } else {
 8475                let worktree = lsp_store
 8476                    .update(cx, |lsp_store, cx| {
 8477                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8478                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8479                        })
 8480                    })?
 8481                    .await?;
 8482                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8483                    lsp_store
 8484                        .update(cx, |lsp_store, cx| {
 8485                            if let Some(local) = lsp_store.as_local_mut() {
 8486                                local.register_language_server_for_invisible_worktree(
 8487                                    &worktree,
 8488                                    language_server_id,
 8489                                    cx,
 8490                                )
 8491                            }
 8492                        })
 8493                        .ok();
 8494                }
 8495                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8496                let relative_path = if let Some(known_path) = known_relative_path {
 8497                    known_path
 8498                } else {
 8499                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8500                        .into_arc()
 8501                };
 8502                (worktree, relative_path)
 8503            };
 8504            let project_path = ProjectPath {
 8505                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8506                path: relative_path,
 8507            };
 8508            lsp_store
 8509                .update(cx, |lsp_store, cx| {
 8510                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8511                        buffer_store.open_buffer(project_path, cx)
 8512                    })
 8513                })?
 8514                .await
 8515        })
 8516    }
 8517
 8518    fn request_multiple_lsp_locally<P, R>(
 8519        &mut self,
 8520        buffer: &Entity<Buffer>,
 8521        position: Option<P>,
 8522        request: R,
 8523        cx: &mut Context<Self>,
 8524    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8525    where
 8526        P: ToOffset,
 8527        R: LspCommand + Clone,
 8528        <R::LspRequest as lsp::request::Request>::Result: Send,
 8529        <R::LspRequest as lsp::request::Request>::Params: Send,
 8530    {
 8531        let Some(local) = self.as_local() else {
 8532            return Task::ready(Vec::new());
 8533        };
 8534
 8535        let snapshot = buffer.read(cx).snapshot();
 8536        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8537
 8538        let server_ids = buffer.update(cx, |buffer, cx| {
 8539            local
 8540                .language_servers_for_buffer(buffer, cx)
 8541                .filter(|(adapter, _)| {
 8542                    scope
 8543                        .as_ref()
 8544                        .map(|scope| scope.language_allowed(&adapter.name))
 8545                        .unwrap_or(true)
 8546                })
 8547                .map(|(_, server)| server.server_id())
 8548                .filter(|server_id| {
 8549                    self.as_local().is_none_or(|local| {
 8550                        local
 8551                            .buffers_opened_in_servers
 8552                            .get(&snapshot.remote_id())
 8553                            .is_some_and(|servers| servers.contains(server_id))
 8554                    })
 8555                })
 8556                .collect::<Vec<_>>()
 8557        });
 8558
 8559        let mut response_results = server_ids
 8560            .into_iter()
 8561            .map(|server_id| {
 8562                let task = self.request_lsp(
 8563                    buffer.clone(),
 8564                    LanguageServerToQuery::Other(server_id),
 8565                    request.clone(),
 8566                    cx,
 8567                );
 8568                async move { (server_id, task.await) }
 8569            })
 8570            .collect::<FuturesUnordered<_>>();
 8571
 8572        cx.background_spawn(async move {
 8573            let mut responses = Vec::with_capacity(response_results.len());
 8574            while let Some((server_id, response_result)) = response_results.next().await {
 8575                match response_result {
 8576                    Ok(response) => responses.push((server_id, response)),
 8577                    // rust-analyzer likes to error with this when its still loading up
 8578                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8579                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8580                }
 8581            }
 8582            responses
 8583        })
 8584    }
 8585
 8586    async fn handle_lsp_get_completions(
 8587        this: Entity<Self>,
 8588        envelope: TypedEnvelope<proto::GetCompletions>,
 8589        mut cx: AsyncApp,
 8590    ) -> Result<proto::GetCompletionsResponse> {
 8591        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8592
 8593        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8594        let buffer_handle = this.update(&mut cx, |this, cx| {
 8595            this.buffer_store.read(cx).get_existing(buffer_id)
 8596        })??;
 8597        let request = GetCompletions::from_proto(
 8598            envelope.payload,
 8599            this.clone(),
 8600            buffer_handle.clone(),
 8601            cx.clone(),
 8602        )
 8603        .await?;
 8604
 8605        let server_to_query = match request.server_id {
 8606            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8607            None => LanguageServerToQuery::FirstCapable,
 8608        };
 8609
 8610        let response = this
 8611            .update(&mut cx, |this, cx| {
 8612                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8613            })?
 8614            .await?;
 8615        this.update(&mut cx, |this, cx| {
 8616            Ok(GetCompletions::response_to_proto(
 8617                response,
 8618                this,
 8619                sender_id,
 8620                &buffer_handle.read(cx).version(),
 8621                cx,
 8622            ))
 8623        })?
 8624    }
 8625
 8626    async fn handle_lsp_command<T: LspCommand>(
 8627        this: Entity<Self>,
 8628        envelope: TypedEnvelope<T::ProtoRequest>,
 8629        mut cx: AsyncApp,
 8630    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8631    where
 8632        <T::LspRequest as lsp::request::Request>::Params: Send,
 8633        <T::LspRequest as lsp::request::Request>::Result: Send,
 8634    {
 8635        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8636        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8637        let buffer_handle = this.update(&mut cx, |this, cx| {
 8638            this.buffer_store.read(cx).get_existing(buffer_id)
 8639        })??;
 8640        let request = T::from_proto(
 8641            envelope.payload,
 8642            this.clone(),
 8643            buffer_handle.clone(),
 8644            cx.clone(),
 8645        )
 8646        .await?;
 8647        let response = this
 8648            .update(&mut cx, |this, cx| {
 8649                this.request_lsp(
 8650                    buffer_handle.clone(),
 8651                    LanguageServerToQuery::FirstCapable,
 8652                    request,
 8653                    cx,
 8654                )
 8655            })?
 8656            .await?;
 8657        this.update(&mut cx, |this, cx| {
 8658            Ok(T::response_to_proto(
 8659                response,
 8660                this,
 8661                sender_id,
 8662                &buffer_handle.read(cx).version(),
 8663                cx,
 8664            ))
 8665        })?
 8666    }
 8667
 8668    async fn handle_lsp_query(
 8669        lsp_store: Entity<Self>,
 8670        envelope: TypedEnvelope<proto::LspQuery>,
 8671        mut cx: AsyncApp,
 8672    ) -> Result<proto::Ack> {
 8673        use proto::lsp_query::Request;
 8674        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8675        let lsp_query = envelope.payload;
 8676        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8677        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8678        match lsp_query.request.context("invalid LSP query request")? {
 8679            Request::GetReferences(get_references) => {
 8680                let position = get_references.position.clone().and_then(deserialize_anchor);
 8681                Self::query_lsp_locally::<GetReferences>(
 8682                    lsp_store,
 8683                    server_id,
 8684                    sender_id,
 8685                    lsp_request_id,
 8686                    get_references,
 8687                    position,
 8688                    &mut cx,
 8689                )
 8690                .await?;
 8691            }
 8692            Request::GetDocumentColor(get_document_color) => {
 8693                Self::query_lsp_locally::<GetDocumentColor>(
 8694                    lsp_store,
 8695                    server_id,
 8696                    sender_id,
 8697                    lsp_request_id,
 8698                    get_document_color,
 8699                    None,
 8700                    &mut cx,
 8701                )
 8702                .await?;
 8703            }
 8704            Request::GetHover(get_hover) => {
 8705                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8706                Self::query_lsp_locally::<GetHover>(
 8707                    lsp_store,
 8708                    server_id,
 8709                    sender_id,
 8710                    lsp_request_id,
 8711                    get_hover,
 8712                    position,
 8713                    &mut cx,
 8714                )
 8715                .await?;
 8716            }
 8717            Request::GetCodeActions(get_code_actions) => {
 8718                Self::query_lsp_locally::<GetCodeActions>(
 8719                    lsp_store,
 8720                    server_id,
 8721                    sender_id,
 8722                    lsp_request_id,
 8723                    get_code_actions,
 8724                    None,
 8725                    &mut cx,
 8726                )
 8727                .await?;
 8728            }
 8729            Request::GetSignatureHelp(get_signature_help) => {
 8730                let position = get_signature_help
 8731                    .position
 8732                    .clone()
 8733                    .and_then(deserialize_anchor);
 8734                Self::query_lsp_locally::<GetSignatureHelp>(
 8735                    lsp_store,
 8736                    server_id,
 8737                    sender_id,
 8738                    lsp_request_id,
 8739                    get_signature_help,
 8740                    position,
 8741                    &mut cx,
 8742                )
 8743                .await?;
 8744            }
 8745            Request::GetCodeLens(get_code_lens) => {
 8746                Self::query_lsp_locally::<GetCodeLens>(
 8747                    lsp_store,
 8748                    server_id,
 8749                    sender_id,
 8750                    lsp_request_id,
 8751                    get_code_lens,
 8752                    None,
 8753                    &mut cx,
 8754                )
 8755                .await?;
 8756            }
 8757            Request::GetDefinition(get_definition) => {
 8758                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8759                Self::query_lsp_locally::<GetDefinitions>(
 8760                    lsp_store,
 8761                    server_id,
 8762                    sender_id,
 8763                    lsp_request_id,
 8764                    get_definition,
 8765                    position,
 8766                    &mut cx,
 8767                )
 8768                .await?;
 8769            }
 8770            Request::GetDeclaration(get_declaration) => {
 8771                let position = get_declaration
 8772                    .position
 8773                    .clone()
 8774                    .and_then(deserialize_anchor);
 8775                Self::query_lsp_locally::<GetDeclarations>(
 8776                    lsp_store,
 8777                    server_id,
 8778                    sender_id,
 8779                    lsp_request_id,
 8780                    get_declaration,
 8781                    position,
 8782                    &mut cx,
 8783                )
 8784                .await?;
 8785            }
 8786            Request::GetTypeDefinition(get_type_definition) => {
 8787                let position = get_type_definition
 8788                    .position
 8789                    .clone()
 8790                    .and_then(deserialize_anchor);
 8791                Self::query_lsp_locally::<GetTypeDefinitions>(
 8792                    lsp_store,
 8793                    server_id,
 8794                    sender_id,
 8795                    lsp_request_id,
 8796                    get_type_definition,
 8797                    position,
 8798                    &mut cx,
 8799                )
 8800                .await?;
 8801            }
 8802            Request::GetImplementation(get_implementation) => {
 8803                let position = get_implementation
 8804                    .position
 8805                    .clone()
 8806                    .and_then(deserialize_anchor);
 8807                Self::query_lsp_locally::<GetImplementations>(
 8808                    lsp_store,
 8809                    server_id,
 8810                    sender_id,
 8811                    lsp_request_id,
 8812                    get_implementation,
 8813                    position,
 8814                    &mut cx,
 8815                )
 8816                .await?;
 8817            }
 8818            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8819                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8820                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8821                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8822                    this.buffer_store.read(cx).get_existing(buffer_id)
 8823                })??;
 8824                buffer
 8825                    .update(&mut cx, |buffer, _| {
 8826                        buffer.wait_for_version(version.clone())
 8827                    })?
 8828                    .await?;
 8829                lsp_store.update(&mut cx, |lsp_store, cx| {
 8830                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8831                    let key = LspKey {
 8832                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8833                        server_queried: server_id,
 8834                    };
 8835                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8836                    ) {
 8837                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8838                            lsp_requests.clear();
 8839                        };
 8840                    }
 8841
 8842                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8843                    existing_queries.insert(
 8844                        lsp_request_id,
 8845                        cx.spawn(async move |lsp_store, cx| {
 8846                            let diagnostics_pull = lsp_store
 8847                                .update(cx, |lsp_store, cx| {
 8848                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8849                                })
 8850                                .ok();
 8851                            if let Some(diagnostics_pull) = diagnostics_pull {
 8852                                match diagnostics_pull.await {
 8853                                    Ok(()) => {}
 8854                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8855                                };
 8856                            }
 8857                        }),
 8858                    );
 8859                })?;
 8860            }
 8861            Request::InlayHints(inlay_hints) => {
 8862                let query_start = inlay_hints
 8863                    .start
 8864                    .clone()
 8865                    .and_then(deserialize_anchor)
 8866                    .context("invalid inlay hints range start")?;
 8867                let query_end = inlay_hints
 8868                    .end
 8869                    .clone()
 8870                    .and_then(deserialize_anchor)
 8871                    .context("invalid inlay hints range end")?;
 8872                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8873                    &lsp_store,
 8874                    server_id,
 8875                    lsp_request_id,
 8876                    &inlay_hints,
 8877                    query_start..query_end,
 8878                    &mut cx,
 8879                )
 8880                .await
 8881                .context("preparing inlay hints request")?;
 8882                Self::query_lsp_locally::<InlayHints>(
 8883                    lsp_store,
 8884                    server_id,
 8885                    sender_id,
 8886                    lsp_request_id,
 8887                    inlay_hints,
 8888                    None,
 8889                    &mut cx,
 8890                )
 8891                .await
 8892                .context("querying for inlay hints")?
 8893            }
 8894        }
 8895        Ok(proto::Ack {})
 8896    }
 8897
 8898    async fn handle_lsp_query_response(
 8899        lsp_store: Entity<Self>,
 8900        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8901        cx: AsyncApp,
 8902    ) -> Result<()> {
 8903        lsp_store.read_with(&cx, |lsp_store, _| {
 8904            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8905                upstream_client.handle_lsp_response(envelope.clone());
 8906            }
 8907        })?;
 8908        Ok(())
 8909    }
 8910
 8911    async fn handle_apply_code_action(
 8912        this: Entity<Self>,
 8913        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8914        mut cx: AsyncApp,
 8915    ) -> Result<proto::ApplyCodeActionResponse> {
 8916        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8917        let action =
 8918            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8919        let apply_code_action = this.update(&mut cx, |this, cx| {
 8920            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8921            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8922            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8923        })??;
 8924
 8925        let project_transaction = apply_code_action.await?;
 8926        let project_transaction = this.update(&mut cx, |this, cx| {
 8927            this.buffer_store.update(cx, |buffer_store, cx| {
 8928                buffer_store.serialize_project_transaction_for_peer(
 8929                    project_transaction,
 8930                    sender_id,
 8931                    cx,
 8932                )
 8933            })
 8934        })?;
 8935        Ok(proto::ApplyCodeActionResponse {
 8936            transaction: Some(project_transaction),
 8937        })
 8938    }
 8939
 8940    async fn handle_register_buffer_with_language_servers(
 8941        this: Entity<Self>,
 8942        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8943        mut cx: AsyncApp,
 8944    ) -> Result<proto::Ack> {
 8945        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8946        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8947        this.update(&mut cx, |this, cx| {
 8948            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8949                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8950                    project_id: upstream_project_id,
 8951                    buffer_id: buffer_id.to_proto(),
 8952                    only_servers: envelope.payload.only_servers,
 8953                });
 8954            }
 8955
 8956            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8957                anyhow::bail!("buffer is not open");
 8958            };
 8959
 8960            let handle = this.register_buffer_with_language_servers(
 8961                &buffer,
 8962                envelope
 8963                    .payload
 8964                    .only_servers
 8965                    .into_iter()
 8966                    .filter_map(|selector| {
 8967                        Some(match selector.selector? {
 8968                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8969                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8970                            }
 8971                            proto::language_server_selector::Selector::Name(name) => {
 8972                                LanguageServerSelector::Name(LanguageServerName(
 8973                                    SharedString::from(name),
 8974                                ))
 8975                            }
 8976                        })
 8977                    })
 8978                    .collect(),
 8979                false,
 8980                cx,
 8981            );
 8982            this.buffer_store().update(cx, |buffer_store, _| {
 8983                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8984            });
 8985
 8986            Ok(())
 8987        })??;
 8988        Ok(proto::Ack {})
 8989    }
 8990
 8991    async fn handle_rename_project_entry(
 8992        this: Entity<Self>,
 8993        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8994        mut cx: AsyncApp,
 8995    ) -> Result<proto::ProjectEntryResponse> {
 8996        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8997        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8998        let new_path =
 8999            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9000
 9001        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9002            .update(&mut cx, |this, cx| {
 9003                let (worktree, entry) = this
 9004                    .worktree_store
 9005                    .read(cx)
 9006                    .worktree_and_entry_for_id(entry_id, cx)?;
 9007                let new_worktree = this
 9008                    .worktree_store
 9009                    .read(cx)
 9010                    .worktree_for_id(new_worktree_id, cx)?;
 9011                Some((
 9012                    this.worktree_store.clone(),
 9013                    worktree,
 9014                    new_worktree,
 9015                    entry.clone(),
 9016                ))
 9017            })?
 9018            .context("worktree not found")?;
 9019        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9020            (worktree.absolutize(&old_entry.path), worktree.id())
 9021        })?;
 9022        let new_abs_path =
 9023            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9024
 9025        let _transaction = Self::will_rename_entry(
 9026            this.downgrade(),
 9027            old_worktree_id,
 9028            &old_abs_path,
 9029            &new_abs_path,
 9030            old_entry.is_dir(),
 9031            cx.clone(),
 9032        )
 9033        .await;
 9034        let response = WorktreeStore::handle_rename_project_entry(
 9035            worktree_store,
 9036            envelope.payload,
 9037            cx.clone(),
 9038        )
 9039        .await;
 9040        this.read_with(&cx, |this, _| {
 9041            this.did_rename_entry(
 9042                old_worktree_id,
 9043                &old_abs_path,
 9044                &new_abs_path,
 9045                old_entry.is_dir(),
 9046            );
 9047        })
 9048        .ok();
 9049        response
 9050    }
 9051
 9052    async fn handle_update_diagnostic_summary(
 9053        this: Entity<Self>,
 9054        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9055        mut cx: AsyncApp,
 9056    ) -> Result<()> {
 9057        this.update(&mut cx, |lsp_store, cx| {
 9058            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9059            let mut updated_diagnostics_paths = HashMap::default();
 9060            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9061            for message_summary in envelope
 9062                .payload
 9063                .summary
 9064                .into_iter()
 9065                .chain(envelope.payload.more_summaries)
 9066            {
 9067                let project_path = ProjectPath {
 9068                    worktree_id,
 9069                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9070                };
 9071                let path = project_path.path.clone();
 9072                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9073                let summary = DiagnosticSummary {
 9074                    error_count: message_summary.error_count as usize,
 9075                    warning_count: message_summary.warning_count as usize,
 9076                };
 9077
 9078                if summary.is_empty() {
 9079                    if let Some(worktree_summaries) =
 9080                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9081                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9082                    {
 9083                        summaries.remove(&server_id);
 9084                        if summaries.is_empty() {
 9085                            worktree_summaries.remove(&path);
 9086                        }
 9087                    }
 9088                } else {
 9089                    lsp_store
 9090                        .diagnostic_summaries
 9091                        .entry(worktree_id)
 9092                        .or_default()
 9093                        .entry(path)
 9094                        .or_default()
 9095                        .insert(server_id, summary);
 9096                }
 9097
 9098                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9099                    match &mut diagnostics_summary {
 9100                        Some(diagnostics_summary) => {
 9101                            diagnostics_summary
 9102                                .more_summaries
 9103                                .push(proto::DiagnosticSummary {
 9104                                    path: project_path.path.as_ref().to_proto(),
 9105                                    language_server_id: server_id.0 as u64,
 9106                                    error_count: summary.error_count as u32,
 9107                                    warning_count: summary.warning_count as u32,
 9108                                })
 9109                        }
 9110                        None => {
 9111                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9112                                project_id: *project_id,
 9113                                worktree_id: worktree_id.to_proto(),
 9114                                summary: Some(proto::DiagnosticSummary {
 9115                                    path: project_path.path.as_ref().to_proto(),
 9116                                    language_server_id: server_id.0 as u64,
 9117                                    error_count: summary.error_count as u32,
 9118                                    warning_count: summary.warning_count as u32,
 9119                                }),
 9120                                more_summaries: Vec::new(),
 9121                            })
 9122                        }
 9123                    }
 9124                }
 9125                updated_diagnostics_paths
 9126                    .entry(server_id)
 9127                    .or_insert_with(Vec::new)
 9128                    .push(project_path);
 9129            }
 9130
 9131            if let Some((diagnostics_summary, (downstream_client, _))) =
 9132                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9133            {
 9134                downstream_client.send(diagnostics_summary).log_err();
 9135            }
 9136            for (server_id, paths) in updated_diagnostics_paths {
 9137                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9138            }
 9139            Ok(())
 9140        })?
 9141    }
 9142
 9143    async fn handle_start_language_server(
 9144        lsp_store: Entity<Self>,
 9145        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9146        mut cx: AsyncApp,
 9147    ) -> Result<()> {
 9148        let server = envelope.payload.server.context("invalid server")?;
 9149        let server_capabilities =
 9150            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9151                .with_context(|| {
 9152                    format!(
 9153                        "incorrect server capabilities {}",
 9154                        envelope.payload.capabilities
 9155                    )
 9156                })?;
 9157        lsp_store.update(&mut cx, |lsp_store, cx| {
 9158            let server_id = LanguageServerId(server.id as usize);
 9159            let server_name = LanguageServerName::from_proto(server.name.clone());
 9160            lsp_store
 9161                .lsp_server_capabilities
 9162                .insert(server_id, server_capabilities);
 9163            lsp_store.language_server_statuses.insert(
 9164                server_id,
 9165                LanguageServerStatus {
 9166                    name: server_name.clone(),
 9167                    pending_work: Default::default(),
 9168                    has_pending_diagnostic_updates: false,
 9169                    progress_tokens: Default::default(),
 9170                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9171                    binary: None,
 9172                    configuration: None,
 9173                    workspace_folders: BTreeSet::new(),
 9174                },
 9175            );
 9176            cx.emit(LspStoreEvent::LanguageServerAdded(
 9177                server_id,
 9178                server_name,
 9179                server.worktree_id.map(WorktreeId::from_proto),
 9180            ));
 9181            cx.notify();
 9182        })?;
 9183        Ok(())
 9184    }
 9185
 9186    async fn handle_update_language_server(
 9187        lsp_store: Entity<Self>,
 9188        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9189        mut cx: AsyncApp,
 9190    ) -> Result<()> {
 9191        lsp_store.update(&mut cx, |lsp_store, cx| {
 9192            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9193
 9194            match envelope.payload.variant.context("invalid variant")? {
 9195                proto::update_language_server::Variant::WorkStart(payload) => {
 9196                    lsp_store.on_lsp_work_start(
 9197                        language_server_id,
 9198                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9199                            .context("invalid progress token value")?,
 9200                        LanguageServerProgress {
 9201                            title: payload.title,
 9202                            is_disk_based_diagnostics_progress: false,
 9203                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9204                            message: payload.message,
 9205                            percentage: payload.percentage.map(|p| p as usize),
 9206                            last_update_at: cx.background_executor().now(),
 9207                        },
 9208                        cx,
 9209                    );
 9210                }
 9211                proto::update_language_server::Variant::WorkProgress(payload) => {
 9212                    lsp_store.on_lsp_work_progress(
 9213                        language_server_id,
 9214                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9215                            .context("invalid progress token value")?,
 9216                        LanguageServerProgress {
 9217                            title: None,
 9218                            is_disk_based_diagnostics_progress: false,
 9219                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9220                            message: payload.message,
 9221                            percentage: payload.percentage.map(|p| p as usize),
 9222                            last_update_at: cx.background_executor().now(),
 9223                        },
 9224                        cx,
 9225                    );
 9226                }
 9227
 9228                proto::update_language_server::Variant::WorkEnd(payload) => {
 9229                    lsp_store.on_lsp_work_end(
 9230                        language_server_id,
 9231                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9232                            .context("invalid progress token value")?,
 9233                        cx,
 9234                    );
 9235                }
 9236
 9237                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9238                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9239                }
 9240
 9241                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9242                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9243                }
 9244
 9245                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9246                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9247                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9248                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9249                        language_server_id,
 9250                        name: envelope
 9251                            .payload
 9252                            .server_name
 9253                            .map(SharedString::new)
 9254                            .map(LanguageServerName),
 9255                        message: non_lsp,
 9256                    });
 9257                }
 9258            }
 9259
 9260            Ok(())
 9261        })?
 9262    }
 9263
 9264    async fn handle_language_server_log(
 9265        this: Entity<Self>,
 9266        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9267        mut cx: AsyncApp,
 9268    ) -> Result<()> {
 9269        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9270        let log_type = envelope
 9271            .payload
 9272            .log_type
 9273            .map(LanguageServerLogType::from_proto)
 9274            .context("invalid language server log type")?;
 9275
 9276        let message = envelope.payload.message;
 9277
 9278        this.update(&mut cx, |_, cx| {
 9279            cx.emit(LspStoreEvent::LanguageServerLog(
 9280                language_server_id,
 9281                log_type,
 9282                message,
 9283            ));
 9284        })
 9285    }
 9286
 9287    async fn handle_lsp_ext_cancel_flycheck(
 9288        lsp_store: Entity<Self>,
 9289        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9290        cx: AsyncApp,
 9291    ) -> Result<proto::Ack> {
 9292        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9293        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9294            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9295                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9296            } else {
 9297                None
 9298            }
 9299        })?;
 9300        if let Some(task) = task {
 9301            task.context("handling lsp ext cancel flycheck")?;
 9302        }
 9303
 9304        Ok(proto::Ack {})
 9305    }
 9306
 9307    async fn handle_lsp_ext_run_flycheck(
 9308        lsp_store: Entity<Self>,
 9309        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9310        mut cx: AsyncApp,
 9311    ) -> Result<proto::Ack> {
 9312        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9313        lsp_store.update(&mut cx, |lsp_store, cx| {
 9314            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9315                let text_document = if envelope.payload.current_file_only {
 9316                    let buffer_id = envelope
 9317                        .payload
 9318                        .buffer_id
 9319                        .map(|id| BufferId::new(id))
 9320                        .transpose()?;
 9321                    buffer_id
 9322                        .and_then(|buffer_id| {
 9323                            lsp_store
 9324                                .buffer_store()
 9325                                .read(cx)
 9326                                .get(buffer_id)
 9327                                .and_then(|buffer| {
 9328                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9329                                })
 9330                                .map(|path| make_text_document_identifier(&path))
 9331                        })
 9332                        .transpose()?
 9333                } else {
 9334                    None
 9335                };
 9336                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9337                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9338                )?;
 9339            }
 9340            anyhow::Ok(())
 9341        })??;
 9342
 9343        Ok(proto::Ack {})
 9344    }
 9345
 9346    async fn handle_lsp_ext_clear_flycheck(
 9347        lsp_store: Entity<Self>,
 9348        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9349        cx: AsyncApp,
 9350    ) -> Result<proto::Ack> {
 9351        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9352        lsp_store
 9353            .read_with(&cx, |lsp_store, _| {
 9354                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9355                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9356                } else {
 9357                    None
 9358                }
 9359            })
 9360            .context("handling lsp ext clear flycheck")?;
 9361
 9362        Ok(proto::Ack {})
 9363    }
 9364
 9365    pub fn disk_based_diagnostics_started(
 9366        &mut self,
 9367        language_server_id: LanguageServerId,
 9368        cx: &mut Context<Self>,
 9369    ) {
 9370        if let Some(language_server_status) =
 9371            self.language_server_statuses.get_mut(&language_server_id)
 9372        {
 9373            language_server_status.has_pending_diagnostic_updates = true;
 9374        }
 9375
 9376        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9377        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9378            language_server_id,
 9379            name: self
 9380                .language_server_adapter_for_id(language_server_id)
 9381                .map(|adapter| adapter.name()),
 9382            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9383                Default::default(),
 9384            ),
 9385        })
 9386    }
 9387
 9388    pub fn disk_based_diagnostics_finished(
 9389        &mut self,
 9390        language_server_id: LanguageServerId,
 9391        cx: &mut Context<Self>,
 9392    ) {
 9393        if let Some(language_server_status) =
 9394            self.language_server_statuses.get_mut(&language_server_id)
 9395        {
 9396            language_server_status.has_pending_diagnostic_updates = false;
 9397        }
 9398
 9399        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9400        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9401            language_server_id,
 9402            name: self
 9403                .language_server_adapter_for_id(language_server_id)
 9404                .map(|adapter| adapter.name()),
 9405            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9406                Default::default(),
 9407            ),
 9408        })
 9409    }
 9410
 9411    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9412    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9413    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9414    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9415    // the language server might take some time to publish diagnostics.
 9416    fn simulate_disk_based_diagnostics_events_if_needed(
 9417        &mut self,
 9418        language_server_id: LanguageServerId,
 9419        cx: &mut Context<Self>,
 9420    ) {
 9421        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9422
 9423        let Some(LanguageServerState::Running {
 9424            simulate_disk_based_diagnostics_completion,
 9425            adapter,
 9426            ..
 9427        }) = self
 9428            .as_local_mut()
 9429            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9430        else {
 9431            return;
 9432        };
 9433
 9434        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9435            return;
 9436        }
 9437
 9438        let prev_task =
 9439            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9440                cx.background_executor()
 9441                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9442                    .await;
 9443
 9444                this.update(cx, |this, cx| {
 9445                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9446
 9447                    if let Some(LanguageServerState::Running {
 9448                        simulate_disk_based_diagnostics_completion,
 9449                        ..
 9450                    }) = this.as_local_mut().and_then(|local_store| {
 9451                        local_store.language_servers.get_mut(&language_server_id)
 9452                    }) {
 9453                        *simulate_disk_based_diagnostics_completion = None;
 9454                    }
 9455                })
 9456                .ok();
 9457            }));
 9458
 9459        if prev_task.is_none() {
 9460            self.disk_based_diagnostics_started(language_server_id, cx);
 9461        }
 9462    }
 9463
 9464    pub fn language_server_statuses(
 9465        &self,
 9466    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9467        self.language_server_statuses
 9468            .iter()
 9469            .map(|(key, value)| (*key, value))
 9470    }
 9471
 9472    pub(super) fn did_rename_entry(
 9473        &self,
 9474        worktree_id: WorktreeId,
 9475        old_path: &Path,
 9476        new_path: &Path,
 9477        is_dir: bool,
 9478    ) {
 9479        maybe!({
 9480            let local_store = self.as_local()?;
 9481
 9482            let old_uri = lsp::Uri::from_file_path(old_path)
 9483                .ok()
 9484                .map(|uri| uri.to_string())?;
 9485            let new_uri = lsp::Uri::from_file_path(new_path)
 9486                .ok()
 9487                .map(|uri| uri.to_string())?;
 9488
 9489            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9490                let Some(filter) = local_store
 9491                    .language_server_paths_watched_for_rename
 9492                    .get(&language_server.server_id())
 9493                else {
 9494                    continue;
 9495                };
 9496
 9497                if filter.should_send_did_rename(&old_uri, is_dir) {
 9498                    language_server
 9499                        .notify::<DidRenameFiles>(RenameFilesParams {
 9500                            files: vec![FileRename {
 9501                                old_uri: old_uri.clone(),
 9502                                new_uri: new_uri.clone(),
 9503                            }],
 9504                        })
 9505                        .ok();
 9506                }
 9507            }
 9508            Some(())
 9509        });
 9510    }
 9511
 9512    pub(super) fn will_rename_entry(
 9513        this: WeakEntity<Self>,
 9514        worktree_id: WorktreeId,
 9515        old_path: &Path,
 9516        new_path: &Path,
 9517        is_dir: bool,
 9518        cx: AsyncApp,
 9519    ) -> Task<ProjectTransaction> {
 9520        let old_uri = lsp::Uri::from_file_path(old_path)
 9521            .ok()
 9522            .map(|uri| uri.to_string());
 9523        let new_uri = lsp::Uri::from_file_path(new_path)
 9524            .ok()
 9525            .map(|uri| uri.to_string());
 9526        cx.spawn(async move |cx| {
 9527            let mut tasks = vec![];
 9528            this.update(cx, |this, cx| {
 9529                let local_store = this.as_local()?;
 9530                let old_uri = old_uri?;
 9531                let new_uri = new_uri?;
 9532                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9533                    let Some(filter) = local_store
 9534                        .language_server_paths_watched_for_rename
 9535                        .get(&language_server.server_id())
 9536                    else {
 9537                        continue;
 9538                    };
 9539
 9540                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9541                        let apply_edit = cx.spawn({
 9542                            let old_uri = old_uri.clone();
 9543                            let new_uri = new_uri.clone();
 9544                            let language_server = language_server.clone();
 9545                            async move |this, cx| {
 9546                                let edit = language_server
 9547                                    .request::<WillRenameFiles>(RenameFilesParams {
 9548                                        files: vec![FileRename { old_uri, new_uri }],
 9549                                    })
 9550                                    .await
 9551                                    .into_response()
 9552                                    .context("will rename files")
 9553                                    .log_err()
 9554                                    .flatten()?;
 9555
 9556                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9557                                    this.upgrade()?,
 9558                                    edit,
 9559                                    false,
 9560                                    language_server.clone(),
 9561                                    cx,
 9562                                )
 9563                                .await
 9564                                .ok()?;
 9565                                Some(transaction)
 9566                            }
 9567                        });
 9568                        tasks.push(apply_edit);
 9569                    }
 9570                }
 9571                Some(())
 9572            })
 9573            .ok()
 9574            .flatten();
 9575            let mut merged_transaction = ProjectTransaction::default();
 9576            for task in tasks {
 9577                // Await on tasks sequentially so that the order of application of edits is deterministic
 9578                // (at least with regards to the order of registration of language servers)
 9579                if let Some(transaction) = task.await {
 9580                    for (buffer, buffer_transaction) in transaction.0 {
 9581                        merged_transaction.0.insert(buffer, buffer_transaction);
 9582                    }
 9583                }
 9584            }
 9585            merged_transaction
 9586        })
 9587    }
 9588
 9589    fn lsp_notify_abs_paths_changed(
 9590        &mut self,
 9591        server_id: LanguageServerId,
 9592        changes: Vec<PathEvent>,
 9593    ) {
 9594        maybe!({
 9595            let server = self.language_server_for_id(server_id)?;
 9596            let changes = changes
 9597                .into_iter()
 9598                .filter_map(|event| {
 9599                    let typ = match event.kind? {
 9600                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9601                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9602                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9603                    };
 9604                    Some(lsp::FileEvent {
 9605                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9606                        typ,
 9607                    })
 9608                })
 9609                .collect::<Vec<_>>();
 9610            if !changes.is_empty() {
 9611                server
 9612                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9613                        lsp::DidChangeWatchedFilesParams { changes },
 9614                    )
 9615                    .ok();
 9616            }
 9617            Some(())
 9618        });
 9619    }
 9620
 9621    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9622        self.as_local()?.language_server_for_id(id)
 9623    }
 9624
 9625    fn on_lsp_progress(
 9626        &mut self,
 9627        progress_params: lsp::ProgressParams,
 9628        language_server_id: LanguageServerId,
 9629        disk_based_diagnostics_progress_token: Option<String>,
 9630        cx: &mut Context<Self>,
 9631    ) {
 9632        match progress_params.value {
 9633            lsp::ProgressParamsValue::WorkDone(progress) => {
 9634                self.handle_work_done_progress(
 9635                    progress,
 9636                    language_server_id,
 9637                    disk_based_diagnostics_progress_token,
 9638                    ProgressToken::from_lsp(progress_params.token),
 9639                    cx,
 9640                );
 9641            }
 9642            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9643                let identifier = match progress_params.token {
 9644                    lsp::NumberOrString::Number(_) => None,
 9645                    lsp::NumberOrString::String(token) => token
 9646                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9647                        .map(|(_, id)| id.to_owned()),
 9648                };
 9649                if let Some(LanguageServerState::Running {
 9650                    workspace_diagnostics_refresh_tasks,
 9651                    ..
 9652                }) = self
 9653                    .as_local_mut()
 9654                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9655                    && let Some(workspace_diagnostics) =
 9656                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9657                {
 9658                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9659                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9660                }
 9661            }
 9662        }
 9663    }
 9664
 9665    fn handle_work_done_progress(
 9666        &mut self,
 9667        progress: lsp::WorkDoneProgress,
 9668        language_server_id: LanguageServerId,
 9669        disk_based_diagnostics_progress_token: Option<String>,
 9670        token: ProgressToken,
 9671        cx: &mut Context<Self>,
 9672    ) {
 9673        let language_server_status =
 9674            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9675                status
 9676            } else {
 9677                return;
 9678            };
 9679
 9680        if !language_server_status.progress_tokens.contains(&token) {
 9681            return;
 9682        }
 9683
 9684        let is_disk_based_diagnostics_progress =
 9685            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9686                (&disk_based_diagnostics_progress_token, &token)
 9687            {
 9688                token.starts_with(disk_based_token)
 9689            } else {
 9690                false
 9691            };
 9692
 9693        match progress {
 9694            lsp::WorkDoneProgress::Begin(report) => {
 9695                if is_disk_based_diagnostics_progress {
 9696                    self.disk_based_diagnostics_started(language_server_id, cx);
 9697                }
 9698                self.on_lsp_work_start(
 9699                    language_server_id,
 9700                    token.clone(),
 9701                    LanguageServerProgress {
 9702                        title: Some(report.title),
 9703                        is_disk_based_diagnostics_progress,
 9704                        is_cancellable: report.cancellable.unwrap_or(false),
 9705                        message: report.message.clone(),
 9706                        percentage: report.percentage.map(|p| p as usize),
 9707                        last_update_at: cx.background_executor().now(),
 9708                    },
 9709                    cx,
 9710                );
 9711            }
 9712            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9713                language_server_id,
 9714                token,
 9715                LanguageServerProgress {
 9716                    title: None,
 9717                    is_disk_based_diagnostics_progress,
 9718                    is_cancellable: report.cancellable.unwrap_or(false),
 9719                    message: report.message,
 9720                    percentage: report.percentage.map(|p| p as usize),
 9721                    last_update_at: cx.background_executor().now(),
 9722                },
 9723                cx,
 9724            ),
 9725            lsp::WorkDoneProgress::End(_) => {
 9726                language_server_status.progress_tokens.remove(&token);
 9727                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9728                if is_disk_based_diagnostics_progress {
 9729                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9730                }
 9731            }
 9732        }
 9733    }
 9734
 9735    fn on_lsp_work_start(
 9736        &mut self,
 9737        language_server_id: LanguageServerId,
 9738        token: ProgressToken,
 9739        progress: LanguageServerProgress,
 9740        cx: &mut Context<Self>,
 9741    ) {
 9742        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9743            status.pending_work.insert(token.clone(), progress.clone());
 9744            cx.notify();
 9745        }
 9746        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9747            language_server_id,
 9748            name: self
 9749                .language_server_adapter_for_id(language_server_id)
 9750                .map(|adapter| adapter.name()),
 9751            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9752                token: Some(token.to_proto()),
 9753                title: progress.title,
 9754                message: progress.message,
 9755                percentage: progress.percentage.map(|p| p as u32),
 9756                is_cancellable: Some(progress.is_cancellable),
 9757            }),
 9758        })
 9759    }
 9760
 9761    fn on_lsp_work_progress(
 9762        &mut self,
 9763        language_server_id: LanguageServerId,
 9764        token: ProgressToken,
 9765        progress: LanguageServerProgress,
 9766        cx: &mut Context<Self>,
 9767    ) {
 9768        let mut did_update = false;
 9769        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9770            match status.pending_work.entry(token.clone()) {
 9771                btree_map::Entry::Vacant(entry) => {
 9772                    entry.insert(progress.clone());
 9773                    did_update = true;
 9774                }
 9775                btree_map::Entry::Occupied(mut entry) => {
 9776                    let entry = entry.get_mut();
 9777                    if (progress.last_update_at - entry.last_update_at)
 9778                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9779                    {
 9780                        entry.last_update_at = progress.last_update_at;
 9781                        if progress.message.is_some() {
 9782                            entry.message = progress.message.clone();
 9783                        }
 9784                        if progress.percentage.is_some() {
 9785                            entry.percentage = progress.percentage;
 9786                        }
 9787                        if progress.is_cancellable != entry.is_cancellable {
 9788                            entry.is_cancellable = progress.is_cancellable;
 9789                        }
 9790                        did_update = true;
 9791                    }
 9792                }
 9793            }
 9794        }
 9795
 9796        if did_update {
 9797            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9798                language_server_id,
 9799                name: self
 9800                    .language_server_adapter_for_id(language_server_id)
 9801                    .map(|adapter| adapter.name()),
 9802                message: proto::update_language_server::Variant::WorkProgress(
 9803                    proto::LspWorkProgress {
 9804                        token: Some(token.to_proto()),
 9805                        message: progress.message,
 9806                        percentage: progress.percentage.map(|p| p as u32),
 9807                        is_cancellable: Some(progress.is_cancellable),
 9808                    },
 9809                ),
 9810            })
 9811        }
 9812    }
 9813
 9814    fn on_lsp_work_end(
 9815        &mut self,
 9816        language_server_id: LanguageServerId,
 9817        token: ProgressToken,
 9818        cx: &mut Context<Self>,
 9819    ) {
 9820        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9821            if let Some(work) = status.pending_work.remove(&token)
 9822                && !work.is_disk_based_diagnostics_progress
 9823            {
 9824                cx.emit(LspStoreEvent::RefreshInlayHints {
 9825                    server_id: language_server_id,
 9826                    request_id: None,
 9827                });
 9828            }
 9829            cx.notify();
 9830        }
 9831
 9832        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9833            language_server_id,
 9834            name: self
 9835                .language_server_adapter_for_id(language_server_id)
 9836                .map(|adapter| adapter.name()),
 9837            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9838                token: Some(token.to_proto()),
 9839            }),
 9840        })
 9841    }
 9842
 9843    pub async fn handle_resolve_completion_documentation(
 9844        this: Entity<Self>,
 9845        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9846        mut cx: AsyncApp,
 9847    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9848        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9849
 9850        let completion = this
 9851            .read_with(&cx, |this, cx| {
 9852                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9853                let server = this
 9854                    .language_server_for_id(id)
 9855                    .with_context(|| format!("No language server {id}"))?;
 9856
 9857                anyhow::Ok(cx.background_spawn(async move {
 9858                    let can_resolve = server
 9859                        .capabilities()
 9860                        .completion_provider
 9861                        .as_ref()
 9862                        .and_then(|options| options.resolve_provider)
 9863                        .unwrap_or(false);
 9864                    if can_resolve {
 9865                        server
 9866                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9867                            .await
 9868                            .into_response()
 9869                            .context("resolve completion item")
 9870                    } else {
 9871                        anyhow::Ok(lsp_completion)
 9872                    }
 9873                }))
 9874            })??
 9875            .await?;
 9876
 9877        let mut documentation_is_markdown = false;
 9878        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9879        let documentation = match completion.documentation {
 9880            Some(lsp::Documentation::String(text)) => text,
 9881
 9882            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9883                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9884                value
 9885            }
 9886
 9887            _ => String::new(),
 9888        };
 9889
 9890        // If we have a new buffer_id, that means we're talking to a new client
 9891        // and want to check for new text_edits in the completion too.
 9892        let mut old_replace_start = None;
 9893        let mut old_replace_end = None;
 9894        let mut old_insert_start = None;
 9895        let mut old_insert_end = None;
 9896        let mut new_text = String::default();
 9897        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9898            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9899                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9900                anyhow::Ok(buffer.read(cx).snapshot())
 9901            })??;
 9902
 9903            if let Some(text_edit) = completion.text_edit.as_ref() {
 9904                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9905
 9906                if let Some(mut edit) = edit {
 9907                    LineEnding::normalize(&mut edit.new_text);
 9908
 9909                    new_text = edit.new_text;
 9910                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9911                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9912                    if let Some(insert_range) = edit.insert_range {
 9913                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9914                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9915                    }
 9916                }
 9917            }
 9918        }
 9919
 9920        Ok(proto::ResolveCompletionDocumentationResponse {
 9921            documentation,
 9922            documentation_is_markdown,
 9923            old_replace_start,
 9924            old_replace_end,
 9925            new_text,
 9926            lsp_completion,
 9927            old_insert_start,
 9928            old_insert_end,
 9929        })
 9930    }
 9931
 9932    async fn handle_on_type_formatting(
 9933        this: Entity<Self>,
 9934        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9935        mut cx: AsyncApp,
 9936    ) -> Result<proto::OnTypeFormattingResponse> {
 9937        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9938            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9939            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9940            let position = envelope
 9941                .payload
 9942                .position
 9943                .and_then(deserialize_anchor)
 9944                .context("invalid position")?;
 9945            anyhow::Ok(this.apply_on_type_formatting(
 9946                buffer,
 9947                position,
 9948                envelope.payload.trigger.clone(),
 9949                cx,
 9950            ))
 9951        })??;
 9952
 9953        let transaction = on_type_formatting
 9954            .await?
 9955            .as_ref()
 9956            .map(language::proto::serialize_transaction);
 9957        Ok(proto::OnTypeFormattingResponse { transaction })
 9958    }
 9959
 9960    async fn handle_refresh_inlay_hints(
 9961        lsp_store: Entity<Self>,
 9962        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9963        mut cx: AsyncApp,
 9964    ) -> Result<proto::Ack> {
 9965        lsp_store.update(&mut cx, |_, cx| {
 9966            cx.emit(LspStoreEvent::RefreshInlayHints {
 9967                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9968                request_id: envelope.payload.request_id.map(|id| id as usize),
 9969            });
 9970        })?;
 9971        Ok(proto::Ack {})
 9972    }
 9973
 9974    async fn handle_pull_workspace_diagnostics(
 9975        lsp_store: Entity<Self>,
 9976        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9977        mut cx: AsyncApp,
 9978    ) -> Result<proto::Ack> {
 9979        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9980        lsp_store.update(&mut cx, |lsp_store, _| {
 9981            lsp_store.pull_workspace_diagnostics(server_id);
 9982        })?;
 9983        Ok(proto::Ack {})
 9984    }
 9985
 9986    async fn handle_get_color_presentation(
 9987        lsp_store: Entity<Self>,
 9988        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9989        mut cx: AsyncApp,
 9990    ) -> Result<proto::GetColorPresentationResponse> {
 9991        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9992        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9993            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9994        })??;
 9995
 9996        let color = envelope
 9997            .payload
 9998            .color
 9999            .context("invalid color resolve request")?;
10000        let start = color
10001            .lsp_range_start
10002            .context("invalid color resolve request")?;
10003        let end = color
10004            .lsp_range_end
10005            .context("invalid color resolve request")?;
10006
10007        let color = DocumentColor {
10008            lsp_range: lsp::Range {
10009                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10010                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10011            },
10012            color: lsp::Color {
10013                red: color.red,
10014                green: color.green,
10015                blue: color.blue,
10016                alpha: color.alpha,
10017            },
10018            resolved: false,
10019            color_presentations: Vec::new(),
10020        };
10021        let resolved_color = lsp_store
10022            .update(&mut cx, |lsp_store, cx| {
10023                lsp_store.resolve_color_presentation(
10024                    color,
10025                    buffer.clone(),
10026                    LanguageServerId(envelope.payload.server_id as usize),
10027                    cx,
10028                )
10029            })?
10030            .await
10031            .context("resolving color presentation")?;
10032
10033        Ok(proto::GetColorPresentationResponse {
10034            presentations: resolved_color
10035                .color_presentations
10036                .into_iter()
10037                .map(|presentation| proto::ColorPresentation {
10038                    label: presentation.label.to_string(),
10039                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10040                    additional_text_edits: presentation
10041                        .additional_text_edits
10042                        .into_iter()
10043                        .map(serialize_lsp_edit)
10044                        .collect(),
10045                })
10046                .collect(),
10047        })
10048    }
10049
10050    async fn handle_resolve_inlay_hint(
10051        lsp_store: Entity<Self>,
10052        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10053        mut cx: AsyncApp,
10054    ) -> Result<proto::ResolveInlayHintResponse> {
10055        let proto_hint = envelope
10056            .payload
10057            .hint
10058            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10059        let hint = InlayHints::proto_to_project_hint(proto_hint)
10060            .context("resolved proto inlay hint conversion")?;
10061        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10062            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10063            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10064        })??;
10065        let response_hint = lsp_store
10066            .update(&mut cx, |lsp_store, cx| {
10067                lsp_store.resolve_inlay_hint(
10068                    hint,
10069                    buffer,
10070                    LanguageServerId(envelope.payload.language_server_id as usize),
10071                    cx,
10072                )
10073            })?
10074            .await
10075            .context("inlay hints fetch")?;
10076        Ok(proto::ResolveInlayHintResponse {
10077            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10078        })
10079    }
10080
10081    async fn handle_refresh_code_lens(
10082        this: Entity<Self>,
10083        _: TypedEnvelope<proto::RefreshCodeLens>,
10084        mut cx: AsyncApp,
10085    ) -> Result<proto::Ack> {
10086        this.update(&mut cx, |_, cx| {
10087            cx.emit(LspStoreEvent::RefreshCodeLens);
10088        })?;
10089        Ok(proto::Ack {})
10090    }
10091
10092    async fn handle_open_buffer_for_symbol(
10093        this: Entity<Self>,
10094        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10095        mut cx: AsyncApp,
10096    ) -> Result<proto::OpenBufferForSymbolResponse> {
10097        let peer_id = envelope.original_sender_id().unwrap_or_default();
10098        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10099        let symbol = Self::deserialize_symbol(symbol)?;
10100        this.read_with(&cx, |this, _| {
10101            if let SymbolLocation::OutsideProject {
10102                abs_path,
10103                signature,
10104            } = &symbol.path
10105            {
10106                let new_signature = this.symbol_signature(&abs_path);
10107                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10108            }
10109            Ok(())
10110        })??;
10111        let buffer = this
10112            .update(&mut cx, |this, cx| {
10113                this.open_buffer_for_symbol(
10114                    &Symbol {
10115                        language_server_name: symbol.language_server_name,
10116                        source_worktree_id: symbol.source_worktree_id,
10117                        source_language_server_id: symbol.source_language_server_id,
10118                        path: symbol.path,
10119                        name: symbol.name,
10120                        kind: symbol.kind,
10121                        range: symbol.range,
10122                        label: CodeLabel::default(),
10123                    },
10124                    cx,
10125                )
10126            })?
10127            .await?;
10128
10129        this.update(&mut cx, |this, cx| {
10130            let is_private = buffer
10131                .read(cx)
10132                .file()
10133                .map(|f| f.is_private())
10134                .unwrap_or_default();
10135            if is_private {
10136                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10137            } else {
10138                this.buffer_store
10139                    .update(cx, |buffer_store, cx| {
10140                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10141                    })
10142                    .detach_and_log_err(cx);
10143                let buffer_id = buffer.read(cx).remote_id().to_proto();
10144                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10145            }
10146        })?
10147    }
10148
10149    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10150        let mut hasher = Sha256::new();
10151        hasher.update(abs_path.to_string_lossy().as_bytes());
10152        hasher.update(self.nonce.to_be_bytes());
10153        hasher.finalize().as_slice().try_into().unwrap()
10154    }
10155
10156    pub async fn handle_get_project_symbols(
10157        this: Entity<Self>,
10158        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10159        mut cx: AsyncApp,
10160    ) -> Result<proto::GetProjectSymbolsResponse> {
10161        let symbols = this
10162            .update(&mut cx, |this, cx| {
10163                this.symbols(&envelope.payload.query, cx)
10164            })?
10165            .await?;
10166
10167        Ok(proto::GetProjectSymbolsResponse {
10168            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10169        })
10170    }
10171
10172    pub async fn handle_restart_language_servers(
10173        this: Entity<Self>,
10174        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10175        mut cx: AsyncApp,
10176    ) -> Result<proto::Ack> {
10177        this.update(&mut cx, |lsp_store, cx| {
10178            let buffers =
10179                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10180            lsp_store.restart_language_servers_for_buffers(
10181                buffers,
10182                envelope
10183                    .payload
10184                    .only_servers
10185                    .into_iter()
10186                    .filter_map(|selector| {
10187                        Some(match selector.selector? {
10188                            proto::language_server_selector::Selector::ServerId(server_id) => {
10189                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10190                            }
10191                            proto::language_server_selector::Selector::Name(name) => {
10192                                LanguageServerSelector::Name(LanguageServerName(
10193                                    SharedString::from(name),
10194                                ))
10195                            }
10196                        })
10197                    })
10198                    .collect(),
10199                cx,
10200            );
10201        })?;
10202
10203        Ok(proto::Ack {})
10204    }
10205
10206    pub async fn handle_stop_language_servers(
10207        lsp_store: Entity<Self>,
10208        envelope: TypedEnvelope<proto::StopLanguageServers>,
10209        mut cx: AsyncApp,
10210    ) -> Result<proto::Ack> {
10211        lsp_store.update(&mut cx, |lsp_store, cx| {
10212            if envelope.payload.all
10213                && envelope.payload.also_servers.is_empty()
10214                && envelope.payload.buffer_ids.is_empty()
10215            {
10216                lsp_store.stop_all_language_servers(cx);
10217            } else {
10218                let buffers =
10219                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10220                lsp_store
10221                    .stop_language_servers_for_buffers(
10222                        buffers,
10223                        envelope
10224                            .payload
10225                            .also_servers
10226                            .into_iter()
10227                            .filter_map(|selector| {
10228                                Some(match selector.selector? {
10229                                    proto::language_server_selector::Selector::ServerId(
10230                                        server_id,
10231                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10232                                        server_id,
10233                                    )),
10234                                    proto::language_server_selector::Selector::Name(name) => {
10235                                        LanguageServerSelector::Name(LanguageServerName(
10236                                            SharedString::from(name),
10237                                        ))
10238                                    }
10239                                })
10240                            })
10241                            .collect(),
10242                        cx,
10243                    )
10244                    .detach_and_log_err(cx);
10245            }
10246        })?;
10247
10248        Ok(proto::Ack {})
10249    }
10250
10251    pub async fn handle_cancel_language_server_work(
10252        lsp_store: Entity<Self>,
10253        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10254        mut cx: AsyncApp,
10255    ) -> Result<proto::Ack> {
10256        lsp_store.update(&mut cx, |lsp_store, cx| {
10257            if let Some(work) = envelope.payload.work {
10258                match work {
10259                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10260                        let buffers =
10261                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10262                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10263                    }
10264                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10265                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10266                        let token = work
10267                            .token
10268                            .map(|token| {
10269                                ProgressToken::from_proto(token)
10270                                    .context("invalid work progress token")
10271                            })
10272                            .transpose()?;
10273                        lsp_store.cancel_language_server_work(server_id, token, cx);
10274                    }
10275                }
10276            }
10277            anyhow::Ok(())
10278        })??;
10279
10280        Ok(proto::Ack {})
10281    }
10282
10283    fn buffer_ids_to_buffers(
10284        &mut self,
10285        buffer_ids: impl Iterator<Item = u64>,
10286        cx: &mut Context<Self>,
10287    ) -> Vec<Entity<Buffer>> {
10288        buffer_ids
10289            .into_iter()
10290            .flat_map(|buffer_id| {
10291                self.buffer_store
10292                    .read(cx)
10293                    .get(BufferId::new(buffer_id).log_err()?)
10294            })
10295            .collect::<Vec<_>>()
10296    }
10297
10298    async fn handle_apply_additional_edits_for_completion(
10299        this: Entity<Self>,
10300        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10301        mut cx: AsyncApp,
10302    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10303        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10304            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10305            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10306            let completion = Self::deserialize_completion(
10307                envelope.payload.completion.context("invalid completion")?,
10308            )?;
10309            anyhow::Ok((buffer, completion))
10310        })??;
10311
10312        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10313            this.apply_additional_edits_for_completion(
10314                buffer,
10315                Rc::new(RefCell::new(Box::new([Completion {
10316                    replace_range: completion.replace_range,
10317                    new_text: completion.new_text,
10318                    source: completion.source,
10319                    documentation: None,
10320                    label: CodeLabel::default(),
10321                    match_start: None,
10322                    snippet_deduplication_key: None,
10323                    insert_text_mode: None,
10324                    icon_path: None,
10325                    confirm: None,
10326                }]))),
10327                0,
10328                false,
10329                cx,
10330            )
10331        })?;
10332
10333        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10334            transaction: apply_additional_edits
10335                .await?
10336                .as_ref()
10337                .map(language::proto::serialize_transaction),
10338        })
10339    }
10340
10341    pub fn last_formatting_failure(&self) -> Option<&str> {
10342        self.last_formatting_failure.as_deref()
10343    }
10344
10345    pub fn reset_last_formatting_failure(&mut self) {
10346        self.last_formatting_failure = None;
10347    }
10348
10349    pub fn environment_for_buffer(
10350        &self,
10351        buffer: &Entity<Buffer>,
10352        cx: &mut Context<Self>,
10353    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10354        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10355            environment.update(cx, |env, cx| {
10356                env.buffer_environment(buffer, &self.worktree_store, cx)
10357            })
10358        } else {
10359            Task::ready(None).shared()
10360        }
10361    }
10362
10363    pub fn format(
10364        &mut self,
10365        buffers: HashSet<Entity<Buffer>>,
10366        target: LspFormatTarget,
10367        push_to_history: bool,
10368        trigger: FormatTrigger,
10369        cx: &mut Context<Self>,
10370    ) -> Task<anyhow::Result<ProjectTransaction>> {
10371        let logger = zlog::scoped!("format");
10372        if self.as_local().is_some() {
10373            zlog::trace!(logger => "Formatting locally");
10374            let logger = zlog::scoped!(logger => "local");
10375            let buffers = buffers
10376                .into_iter()
10377                .map(|buffer_handle| {
10378                    let buffer = buffer_handle.read(cx);
10379                    let buffer_abs_path = File::from_dyn(buffer.file())
10380                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10381
10382                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10383                })
10384                .collect::<Vec<_>>();
10385
10386            cx.spawn(async move |lsp_store, cx| {
10387                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10388
10389                for (handle, abs_path, id) in buffers {
10390                    let env = lsp_store
10391                        .update(cx, |lsp_store, cx| {
10392                            lsp_store.environment_for_buffer(&handle, cx)
10393                        })?
10394                        .await;
10395
10396                    let ranges = match &target {
10397                        LspFormatTarget::Buffers => None,
10398                        LspFormatTarget::Ranges(ranges) => {
10399                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10400                        }
10401                    };
10402
10403                    formattable_buffers.push(FormattableBuffer {
10404                        handle,
10405                        abs_path,
10406                        env,
10407                        ranges,
10408                    });
10409                }
10410                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10411
10412                let format_timer = zlog::time!(logger => "Formatting buffers");
10413                let result = LocalLspStore::format_locally(
10414                    lsp_store.clone(),
10415                    formattable_buffers,
10416                    push_to_history,
10417                    trigger,
10418                    logger,
10419                    cx,
10420                )
10421                .await;
10422                format_timer.end();
10423
10424                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10425
10426                lsp_store.update(cx, |lsp_store, _| {
10427                    lsp_store.update_last_formatting_failure(&result);
10428                })?;
10429
10430                result
10431            })
10432        } else if let Some((client, project_id)) = self.upstream_client() {
10433            zlog::trace!(logger => "Formatting remotely");
10434            let logger = zlog::scoped!(logger => "remote");
10435            // Don't support formatting ranges via remote
10436            match target {
10437                LspFormatTarget::Buffers => {}
10438                LspFormatTarget::Ranges(_) => {
10439                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10440                    return Task::ready(Ok(ProjectTransaction::default()));
10441                }
10442            }
10443
10444            let buffer_store = self.buffer_store();
10445            cx.spawn(async move |lsp_store, cx| {
10446                zlog::trace!(logger => "Sending remote format request");
10447                let request_timer = zlog::time!(logger => "remote format request");
10448                let result = client
10449                    .request(proto::FormatBuffers {
10450                        project_id,
10451                        trigger: trigger as i32,
10452                        buffer_ids: buffers
10453                            .iter()
10454                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10455                            .collect::<Result<_>>()?,
10456                    })
10457                    .await
10458                    .and_then(|result| result.transaction.context("missing transaction"));
10459                request_timer.end();
10460
10461                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10462
10463                lsp_store.update(cx, |lsp_store, _| {
10464                    lsp_store.update_last_formatting_failure(&result);
10465                })?;
10466
10467                let transaction_response = result?;
10468                let _timer = zlog::time!(logger => "deserializing project transaction");
10469                buffer_store
10470                    .update(cx, |buffer_store, cx| {
10471                        buffer_store.deserialize_project_transaction(
10472                            transaction_response,
10473                            push_to_history,
10474                            cx,
10475                        )
10476                    })?
10477                    .await
10478            })
10479        } else {
10480            zlog::trace!(logger => "Not formatting");
10481            Task::ready(Ok(ProjectTransaction::default()))
10482        }
10483    }
10484
10485    async fn handle_format_buffers(
10486        this: Entity<Self>,
10487        envelope: TypedEnvelope<proto::FormatBuffers>,
10488        mut cx: AsyncApp,
10489    ) -> Result<proto::FormatBuffersResponse> {
10490        let sender_id = envelope.original_sender_id().unwrap_or_default();
10491        let format = this.update(&mut cx, |this, cx| {
10492            let mut buffers = HashSet::default();
10493            for buffer_id in &envelope.payload.buffer_ids {
10494                let buffer_id = BufferId::new(*buffer_id)?;
10495                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10496            }
10497            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10498            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10499        })??;
10500
10501        let project_transaction = format.await?;
10502        let project_transaction = this.update(&mut cx, |this, cx| {
10503            this.buffer_store.update(cx, |buffer_store, cx| {
10504                buffer_store.serialize_project_transaction_for_peer(
10505                    project_transaction,
10506                    sender_id,
10507                    cx,
10508                )
10509            })
10510        })?;
10511        Ok(proto::FormatBuffersResponse {
10512            transaction: Some(project_transaction),
10513        })
10514    }
10515
10516    async fn handle_apply_code_action_kind(
10517        this: Entity<Self>,
10518        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10519        mut cx: AsyncApp,
10520    ) -> Result<proto::ApplyCodeActionKindResponse> {
10521        let sender_id = envelope.original_sender_id().unwrap_or_default();
10522        let format = this.update(&mut cx, |this, cx| {
10523            let mut buffers = HashSet::default();
10524            for buffer_id in &envelope.payload.buffer_ids {
10525                let buffer_id = BufferId::new(*buffer_id)?;
10526                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10527            }
10528            let kind = match envelope.payload.kind.as_str() {
10529                "" => CodeActionKind::EMPTY,
10530                "quickfix" => CodeActionKind::QUICKFIX,
10531                "refactor" => CodeActionKind::REFACTOR,
10532                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10533                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10534                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10535                "source" => CodeActionKind::SOURCE,
10536                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10537                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10538                _ => anyhow::bail!(
10539                    "Invalid code action kind {}",
10540                    envelope.payload.kind.as_str()
10541                ),
10542            };
10543            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10544        })??;
10545
10546        let project_transaction = format.await?;
10547        let project_transaction = this.update(&mut cx, |this, cx| {
10548            this.buffer_store.update(cx, |buffer_store, cx| {
10549                buffer_store.serialize_project_transaction_for_peer(
10550                    project_transaction,
10551                    sender_id,
10552                    cx,
10553                )
10554            })
10555        })?;
10556        Ok(proto::ApplyCodeActionKindResponse {
10557            transaction: Some(project_transaction),
10558        })
10559    }
10560
10561    async fn shutdown_language_server(
10562        server_state: Option<LanguageServerState>,
10563        name: LanguageServerName,
10564        cx: &mut AsyncApp,
10565    ) {
10566        let server = match server_state {
10567            Some(LanguageServerState::Starting { startup, .. }) => {
10568                let mut timer = cx
10569                    .background_executor()
10570                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10571                    .fuse();
10572
10573                select! {
10574                    server = startup.fuse() => server,
10575                    () = timer => {
10576                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10577                        None
10578                    },
10579                }
10580            }
10581
10582            Some(LanguageServerState::Running { server, .. }) => Some(server),
10583
10584            None => None,
10585        };
10586
10587        if let Some(server) = server
10588            && let Some(shutdown) = server.shutdown()
10589        {
10590            shutdown.await;
10591        }
10592    }
10593
10594    // Returns a list of all of the worktrees which no longer have a language server and the root path
10595    // for the stopped server
10596    fn stop_local_language_server(
10597        &mut self,
10598        server_id: LanguageServerId,
10599        cx: &mut Context<Self>,
10600    ) -> Task<()> {
10601        let local = match &mut self.mode {
10602            LspStoreMode::Local(local) => local,
10603            _ => {
10604                return Task::ready(());
10605            }
10606        };
10607
10608        // Remove this server ID from all entries in the given worktree.
10609        local
10610            .language_server_ids
10611            .retain(|_, state| state.id != server_id);
10612        self.buffer_store.update(cx, |buffer_store, cx| {
10613            for buffer in buffer_store.buffers() {
10614                buffer.update(cx, |buffer, cx| {
10615                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10616                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10617                });
10618            }
10619        });
10620
10621        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10622            summaries.retain(|path, summaries_by_server_id| {
10623                if summaries_by_server_id.remove(&server_id).is_some() {
10624                    if let Some((client, project_id)) = self.downstream_client.clone() {
10625                        client
10626                            .send(proto::UpdateDiagnosticSummary {
10627                                project_id,
10628                                worktree_id: worktree_id.to_proto(),
10629                                summary: Some(proto::DiagnosticSummary {
10630                                    path: path.as_ref().to_proto(),
10631                                    language_server_id: server_id.0 as u64,
10632                                    error_count: 0,
10633                                    warning_count: 0,
10634                                }),
10635                                more_summaries: Vec::new(),
10636                            })
10637                            .log_err();
10638                    }
10639                    !summaries_by_server_id.is_empty()
10640                } else {
10641                    true
10642                }
10643            });
10644        }
10645
10646        let local = self.as_local_mut().unwrap();
10647        for diagnostics in local.diagnostics.values_mut() {
10648            diagnostics.retain(|_, diagnostics_by_server_id| {
10649                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10650                    diagnostics_by_server_id.remove(ix);
10651                    !diagnostics_by_server_id.is_empty()
10652                } else {
10653                    true
10654                }
10655            });
10656        }
10657        local.language_server_watched_paths.remove(&server_id);
10658
10659        let server_state = local.language_servers.remove(&server_id);
10660        self.cleanup_lsp_data(server_id);
10661        let name = self
10662            .language_server_statuses
10663            .remove(&server_id)
10664            .map(|status| status.name)
10665            .or_else(|| {
10666                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10667                    Some(adapter.name())
10668                } else {
10669                    None
10670                }
10671            });
10672
10673        if let Some(name) = name {
10674            log::info!("stopping language server {name}");
10675            self.languages
10676                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10677            cx.notify();
10678
10679            return cx.spawn(async move |lsp_store, cx| {
10680                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10681                lsp_store
10682                    .update(cx, |lsp_store, cx| {
10683                        lsp_store
10684                            .languages
10685                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10686                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10687                        cx.notify();
10688                    })
10689                    .ok();
10690            });
10691        }
10692
10693        if server_state.is_some() {
10694            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10695        }
10696        Task::ready(())
10697    }
10698
10699    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10700        if let Some((client, project_id)) = self.upstream_client() {
10701            let request = client.request(proto::StopLanguageServers {
10702                project_id,
10703                buffer_ids: Vec::new(),
10704                also_servers: Vec::new(),
10705                all: true,
10706            });
10707            cx.background_spawn(request).detach_and_log_err(cx);
10708        } else {
10709            let Some(local) = self.as_local_mut() else {
10710                return;
10711            };
10712            let language_servers_to_stop = local
10713                .language_server_ids
10714                .values()
10715                .map(|state| state.id)
10716                .collect();
10717            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10718            let tasks = language_servers_to_stop
10719                .into_iter()
10720                .map(|server| self.stop_local_language_server(server, cx))
10721                .collect::<Vec<_>>();
10722            cx.background_spawn(async move {
10723                futures::future::join_all(tasks).await;
10724            })
10725            .detach();
10726        }
10727    }
10728
10729    pub fn restart_language_servers_for_buffers(
10730        &mut self,
10731        buffers: Vec<Entity<Buffer>>,
10732        only_restart_servers: HashSet<LanguageServerSelector>,
10733        cx: &mut Context<Self>,
10734    ) {
10735        if let Some((client, project_id)) = self.upstream_client() {
10736            let request = client.request(proto::RestartLanguageServers {
10737                project_id,
10738                buffer_ids: buffers
10739                    .into_iter()
10740                    .map(|b| b.read(cx).remote_id().to_proto())
10741                    .collect(),
10742                only_servers: only_restart_servers
10743                    .into_iter()
10744                    .map(|selector| {
10745                        let selector = match selector {
10746                            LanguageServerSelector::Id(language_server_id) => {
10747                                proto::language_server_selector::Selector::ServerId(
10748                                    language_server_id.to_proto(),
10749                                )
10750                            }
10751                            LanguageServerSelector::Name(language_server_name) => {
10752                                proto::language_server_selector::Selector::Name(
10753                                    language_server_name.to_string(),
10754                                )
10755                            }
10756                        };
10757                        proto::LanguageServerSelector {
10758                            selector: Some(selector),
10759                        }
10760                    })
10761                    .collect(),
10762                all: false,
10763            });
10764            cx.background_spawn(request).detach_and_log_err(cx);
10765        } else {
10766            let stop_task = if only_restart_servers.is_empty() {
10767                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10768            } else {
10769                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10770            };
10771            cx.spawn(async move |lsp_store, cx| {
10772                stop_task.await;
10773                lsp_store
10774                    .update(cx, |lsp_store, cx| {
10775                        for buffer in buffers {
10776                            lsp_store.register_buffer_with_language_servers(
10777                                &buffer,
10778                                only_restart_servers.clone(),
10779                                true,
10780                                cx,
10781                            );
10782                        }
10783                    })
10784                    .ok()
10785            })
10786            .detach();
10787        }
10788    }
10789
10790    pub fn stop_language_servers_for_buffers(
10791        &mut self,
10792        buffers: Vec<Entity<Buffer>>,
10793        also_stop_servers: HashSet<LanguageServerSelector>,
10794        cx: &mut Context<Self>,
10795    ) -> Task<Result<()>> {
10796        if let Some((client, project_id)) = self.upstream_client() {
10797            let request = client.request(proto::StopLanguageServers {
10798                project_id,
10799                buffer_ids: buffers
10800                    .into_iter()
10801                    .map(|b| b.read(cx).remote_id().to_proto())
10802                    .collect(),
10803                also_servers: also_stop_servers
10804                    .into_iter()
10805                    .map(|selector| {
10806                        let selector = match selector {
10807                            LanguageServerSelector::Id(language_server_id) => {
10808                                proto::language_server_selector::Selector::ServerId(
10809                                    language_server_id.to_proto(),
10810                                )
10811                            }
10812                            LanguageServerSelector::Name(language_server_name) => {
10813                                proto::language_server_selector::Selector::Name(
10814                                    language_server_name.to_string(),
10815                                )
10816                            }
10817                        };
10818                        proto::LanguageServerSelector {
10819                            selector: Some(selector),
10820                        }
10821                    })
10822                    .collect(),
10823                all: false,
10824            });
10825            cx.background_spawn(async move {
10826                let _ = request.await?;
10827                Ok(())
10828            })
10829        } else {
10830            let task =
10831                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10832            cx.background_spawn(async move {
10833                task.await;
10834                Ok(())
10835            })
10836        }
10837    }
10838
10839    fn stop_local_language_servers_for_buffers(
10840        &mut self,
10841        buffers: &[Entity<Buffer>],
10842        also_stop_servers: HashSet<LanguageServerSelector>,
10843        cx: &mut Context<Self>,
10844    ) -> Task<()> {
10845        let Some(local) = self.as_local_mut() else {
10846            return Task::ready(());
10847        };
10848        let mut language_server_names_to_stop = BTreeSet::default();
10849        let mut language_servers_to_stop = also_stop_servers
10850            .into_iter()
10851            .flat_map(|selector| match selector {
10852                LanguageServerSelector::Id(id) => Some(id),
10853                LanguageServerSelector::Name(name) => {
10854                    language_server_names_to_stop.insert(name);
10855                    None
10856                }
10857            })
10858            .collect::<BTreeSet<_>>();
10859
10860        let mut covered_worktrees = HashSet::default();
10861        for buffer in buffers {
10862            buffer.update(cx, |buffer, cx| {
10863                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10864                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10865                    && covered_worktrees.insert(worktree_id)
10866                {
10867                    language_server_names_to_stop.retain(|name| {
10868                        let old_ids_count = language_servers_to_stop.len();
10869                        let all_language_servers_with_this_name = local
10870                            .language_server_ids
10871                            .iter()
10872                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10873                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10874                        old_ids_count == language_servers_to_stop.len()
10875                    });
10876                }
10877            });
10878        }
10879        for name in language_server_names_to_stop {
10880            language_servers_to_stop.extend(
10881                local
10882                    .language_server_ids
10883                    .iter()
10884                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10885            );
10886        }
10887
10888        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10889        let tasks = language_servers_to_stop
10890            .into_iter()
10891            .map(|server| self.stop_local_language_server(server, cx))
10892            .collect::<Vec<_>>();
10893
10894        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10895    }
10896
10897    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10898        let (worktree, relative_path) =
10899            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10900
10901        let project_path = ProjectPath {
10902            worktree_id: worktree.read(cx).id(),
10903            path: relative_path,
10904        };
10905
10906        Some(
10907            self.buffer_store()
10908                .read(cx)
10909                .get_by_path(&project_path)?
10910                .read(cx),
10911        )
10912    }
10913
10914    #[cfg(any(test, feature = "test-support"))]
10915    pub fn update_diagnostics(
10916        &mut self,
10917        server_id: LanguageServerId,
10918        diagnostics: lsp::PublishDiagnosticsParams,
10919        result_id: Option<String>,
10920        source_kind: DiagnosticSourceKind,
10921        disk_based_sources: &[String],
10922        cx: &mut Context<Self>,
10923    ) -> Result<()> {
10924        self.merge_lsp_diagnostics(
10925            source_kind,
10926            vec![DocumentDiagnosticsUpdate {
10927                diagnostics,
10928                result_id,
10929                server_id,
10930                disk_based_sources: Cow::Borrowed(disk_based_sources),
10931            }],
10932            |_, _, _| false,
10933            cx,
10934        )
10935    }
10936
10937    pub fn merge_lsp_diagnostics(
10938        &mut self,
10939        source_kind: DiagnosticSourceKind,
10940        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10941        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10942        cx: &mut Context<Self>,
10943    ) -> Result<()> {
10944        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10945        let updates = lsp_diagnostics
10946            .into_iter()
10947            .filter_map(|update| {
10948                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10949                Some(DocumentDiagnosticsUpdate {
10950                    diagnostics: self.lsp_to_document_diagnostics(
10951                        abs_path,
10952                        source_kind,
10953                        update.server_id,
10954                        update.diagnostics,
10955                        &update.disk_based_sources,
10956                    ),
10957                    result_id: update.result_id,
10958                    server_id: update.server_id,
10959                    disk_based_sources: update.disk_based_sources,
10960                })
10961            })
10962            .collect();
10963        self.merge_diagnostic_entries(updates, merge, cx)?;
10964        Ok(())
10965    }
10966
10967    fn lsp_to_document_diagnostics(
10968        &mut self,
10969        document_abs_path: PathBuf,
10970        source_kind: DiagnosticSourceKind,
10971        server_id: LanguageServerId,
10972        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10973        disk_based_sources: &[String],
10974    ) -> DocumentDiagnostics {
10975        let mut diagnostics = Vec::default();
10976        let mut primary_diagnostic_group_ids = HashMap::default();
10977        let mut sources_by_group_id = HashMap::default();
10978        let mut supporting_diagnostics = HashMap::default();
10979
10980        let adapter = self.language_server_adapter_for_id(server_id);
10981
10982        // Ensure that primary diagnostics are always the most severe
10983        lsp_diagnostics
10984            .diagnostics
10985            .sort_by_key(|item| item.severity);
10986
10987        for diagnostic in &lsp_diagnostics.diagnostics {
10988            let source = diagnostic.source.as_ref();
10989            let range = range_from_lsp(diagnostic.range);
10990            let is_supporting = diagnostic
10991                .related_information
10992                .as_ref()
10993                .is_some_and(|infos| {
10994                    infos.iter().any(|info| {
10995                        primary_diagnostic_group_ids.contains_key(&(
10996                            source,
10997                            diagnostic.code.clone(),
10998                            range_from_lsp(info.location.range),
10999                        ))
11000                    })
11001                });
11002
11003            let is_unnecessary = diagnostic
11004                .tags
11005                .as_ref()
11006                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11007
11008            let underline = self
11009                .language_server_adapter_for_id(server_id)
11010                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11011
11012            if is_supporting {
11013                supporting_diagnostics.insert(
11014                    (source, diagnostic.code.clone(), range),
11015                    (diagnostic.severity, is_unnecessary),
11016                );
11017            } else {
11018                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11019                let is_disk_based =
11020                    source.is_some_and(|source| disk_based_sources.contains(source));
11021
11022                sources_by_group_id.insert(group_id, source);
11023                primary_diagnostic_group_ids
11024                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11025
11026                diagnostics.push(DiagnosticEntry {
11027                    range,
11028                    diagnostic: Diagnostic {
11029                        source: diagnostic.source.clone(),
11030                        source_kind,
11031                        code: diagnostic.code.clone(),
11032                        code_description: diagnostic
11033                            .code_description
11034                            .as_ref()
11035                            .and_then(|d| d.href.clone()),
11036                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11037                        markdown: adapter.as_ref().and_then(|adapter| {
11038                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11039                        }),
11040                        message: diagnostic.message.trim().to_string(),
11041                        group_id,
11042                        is_primary: true,
11043                        is_disk_based,
11044                        is_unnecessary,
11045                        underline,
11046                        data: diagnostic.data.clone(),
11047                    },
11048                });
11049                if let Some(infos) = &diagnostic.related_information {
11050                    for info in infos {
11051                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11052                            let range = range_from_lsp(info.location.range);
11053                            diagnostics.push(DiagnosticEntry {
11054                                range,
11055                                diagnostic: Diagnostic {
11056                                    source: diagnostic.source.clone(),
11057                                    source_kind,
11058                                    code: diagnostic.code.clone(),
11059                                    code_description: diagnostic
11060                                        .code_description
11061                                        .as_ref()
11062                                        .and_then(|d| d.href.clone()),
11063                                    severity: DiagnosticSeverity::INFORMATION,
11064                                    markdown: adapter.as_ref().and_then(|adapter| {
11065                                        adapter.diagnostic_message_to_markdown(&info.message)
11066                                    }),
11067                                    message: info.message.trim().to_string(),
11068                                    group_id,
11069                                    is_primary: false,
11070                                    is_disk_based,
11071                                    is_unnecessary: false,
11072                                    underline,
11073                                    data: diagnostic.data.clone(),
11074                                },
11075                            });
11076                        }
11077                    }
11078                }
11079            }
11080        }
11081
11082        for entry in &mut diagnostics {
11083            let diagnostic = &mut entry.diagnostic;
11084            if !diagnostic.is_primary {
11085                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11086                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11087                    source,
11088                    diagnostic.code.clone(),
11089                    entry.range.clone(),
11090                )) {
11091                    if let Some(severity) = severity {
11092                        diagnostic.severity = severity;
11093                    }
11094                    diagnostic.is_unnecessary = is_unnecessary;
11095                }
11096            }
11097        }
11098
11099        DocumentDiagnostics {
11100            diagnostics,
11101            document_abs_path,
11102            version: lsp_diagnostics.version,
11103        }
11104    }
11105
11106    fn insert_newly_running_language_server(
11107        &mut self,
11108        adapter: Arc<CachedLspAdapter>,
11109        language_server: Arc<LanguageServer>,
11110        server_id: LanguageServerId,
11111        key: LanguageServerSeed,
11112        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11113        cx: &mut Context<Self>,
11114    ) {
11115        let Some(local) = self.as_local_mut() else {
11116            return;
11117        };
11118        // If the language server for this key doesn't match the server id, don't store the
11119        // server. Which will cause it to be dropped, killing the process
11120        if local
11121            .language_server_ids
11122            .get(&key)
11123            .map(|state| state.id != server_id)
11124            .unwrap_or(false)
11125        {
11126            return;
11127        }
11128
11129        // Update language_servers collection with Running variant of LanguageServerState
11130        // indicating that the server is up and running and ready
11131        let workspace_folders = workspace_folders.lock().clone();
11132        language_server.set_workspace_folders(workspace_folders);
11133
11134        let workspace_diagnostics_refresh_tasks = language_server
11135            .capabilities()
11136            .diagnostic_provider
11137            .and_then(|provider| {
11138                local
11139                    .language_server_dynamic_registrations
11140                    .entry(server_id)
11141                    .or_default()
11142                    .diagnostics
11143                    .entry(None)
11144                    .or_insert(provider.clone());
11145                let workspace_refresher =
11146                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11147
11148                Some((None, workspace_refresher))
11149            })
11150            .into_iter()
11151            .collect();
11152        local.language_servers.insert(
11153            server_id,
11154            LanguageServerState::Running {
11155                workspace_diagnostics_refresh_tasks,
11156                adapter: adapter.clone(),
11157                server: language_server.clone(),
11158                simulate_disk_based_diagnostics_completion: None,
11159            },
11160        );
11161        local
11162            .languages
11163            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11164        if let Some(file_ops_caps) = language_server
11165            .capabilities()
11166            .workspace
11167            .as_ref()
11168            .and_then(|ws| ws.file_operations.as_ref())
11169        {
11170            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11171            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11172            if did_rename_caps.or(will_rename_caps).is_some() {
11173                let watcher = RenamePathsWatchedForServer::default()
11174                    .with_did_rename_patterns(did_rename_caps)
11175                    .with_will_rename_patterns(will_rename_caps);
11176                local
11177                    .language_server_paths_watched_for_rename
11178                    .insert(server_id, watcher);
11179            }
11180        }
11181
11182        self.language_server_statuses.insert(
11183            server_id,
11184            LanguageServerStatus {
11185                name: language_server.name(),
11186                pending_work: Default::default(),
11187                has_pending_diagnostic_updates: false,
11188                progress_tokens: Default::default(),
11189                worktree: Some(key.worktree_id),
11190                binary: Some(LanguageServerBinaryInfo {
11191                    path: language_server.binary().path.to_string_lossy().into_owned(),
11192                    arguments: language_server
11193                        .binary()
11194                        .arguments
11195                        .iter()
11196                        .map(|arg| arg.to_string_lossy().into_owned())
11197                        .collect(),
11198                    env: language_server.binary().env.clone(),
11199                }),
11200                configuration: Some(language_server.configuration().clone()),
11201                workspace_folders: language_server.workspace_folders(),
11202            },
11203        );
11204
11205        cx.emit(LspStoreEvent::LanguageServerAdded(
11206            server_id,
11207            language_server.name(),
11208            Some(key.worktree_id),
11209        ));
11210
11211        let server_capabilities = language_server.capabilities();
11212        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11213            downstream_client
11214                .send(proto::StartLanguageServer {
11215                    project_id: *project_id,
11216                    server: Some(proto::LanguageServer {
11217                        id: server_id.to_proto(),
11218                        name: language_server.name().to_string(),
11219                        worktree_id: Some(key.worktree_id.to_proto()),
11220                    }),
11221                    capabilities: serde_json::to_string(&server_capabilities)
11222                        .expect("serializing server LSP capabilities"),
11223                })
11224                .log_err();
11225        }
11226        self.lsp_server_capabilities
11227            .insert(server_id, server_capabilities);
11228
11229        // Tell the language server about every open buffer in the worktree that matches the language.
11230        // Also check for buffers in worktrees that reused this server
11231        let mut worktrees_using_server = vec![key.worktree_id];
11232        if let Some(local) = self.as_local() {
11233            // Find all worktrees that have this server in their language server tree
11234            for (worktree_id, servers) in &local.lsp_tree.instances {
11235                if *worktree_id != key.worktree_id {
11236                    for server_map in servers.roots.values() {
11237                        if server_map
11238                            .values()
11239                            .any(|(node, _)| node.id() == Some(server_id))
11240                        {
11241                            worktrees_using_server.push(*worktree_id);
11242                        }
11243                    }
11244                }
11245            }
11246        }
11247
11248        let mut buffer_paths_registered = Vec::new();
11249        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11250            let mut lsp_adapters = HashMap::default();
11251            for buffer_handle in buffer_store.buffers() {
11252                let buffer = buffer_handle.read(cx);
11253                let file = match File::from_dyn(buffer.file()) {
11254                    Some(file) => file,
11255                    None => continue,
11256                };
11257                let language = match buffer.language() {
11258                    Some(language) => language,
11259                    None => continue,
11260                };
11261
11262                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11263                    || !lsp_adapters
11264                        .entry(language.name())
11265                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11266                        .iter()
11267                        .any(|a| a.name == key.name)
11268                {
11269                    continue;
11270                }
11271                // didOpen
11272                let file = match file.as_local() {
11273                    Some(file) => file,
11274                    None => continue,
11275                };
11276
11277                let local = self.as_local_mut().unwrap();
11278
11279                let buffer_id = buffer.remote_id();
11280                if local.registered_buffers.contains_key(&buffer_id) {
11281                    let versions = local
11282                        .buffer_snapshots
11283                        .entry(buffer_id)
11284                        .or_default()
11285                        .entry(server_id)
11286                        .and_modify(|_| {
11287                            assert!(
11288                            false,
11289                            "There should not be an existing snapshot for a newly inserted buffer"
11290                        )
11291                        })
11292                        .or_insert_with(|| {
11293                            vec![LspBufferSnapshot {
11294                                version: 0,
11295                                snapshot: buffer.text_snapshot(),
11296                            }]
11297                        });
11298
11299                    let snapshot = versions.last().unwrap();
11300                    let version = snapshot.version;
11301                    let initial_snapshot = &snapshot.snapshot;
11302                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11303                    language_server.register_buffer(
11304                        uri,
11305                        adapter.language_id(&language.name()),
11306                        version,
11307                        initial_snapshot.text(),
11308                    );
11309                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11310                    local
11311                        .buffers_opened_in_servers
11312                        .entry(buffer_id)
11313                        .or_default()
11314                        .insert(server_id);
11315                }
11316                buffer_handle.update(cx, |buffer, cx| {
11317                    buffer.set_completion_triggers(
11318                        server_id,
11319                        language_server
11320                            .capabilities()
11321                            .completion_provider
11322                            .as_ref()
11323                            .and_then(|provider| {
11324                                provider
11325                                    .trigger_characters
11326                                    .as_ref()
11327                                    .map(|characters| characters.iter().cloned().collect())
11328                            })
11329                            .unwrap_or_default(),
11330                        cx,
11331                    )
11332                });
11333            }
11334        });
11335
11336        for (buffer_id, abs_path) in buffer_paths_registered {
11337            cx.emit(LspStoreEvent::LanguageServerUpdate {
11338                language_server_id: server_id,
11339                name: Some(adapter.name()),
11340                message: proto::update_language_server::Variant::RegisteredForBuffer(
11341                    proto::RegisteredForBuffer {
11342                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11343                        buffer_id: buffer_id.to_proto(),
11344                    },
11345                ),
11346            });
11347        }
11348
11349        cx.notify();
11350    }
11351
11352    pub fn language_servers_running_disk_based_diagnostics(
11353        &self,
11354    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11355        self.language_server_statuses
11356            .iter()
11357            .filter_map(|(id, status)| {
11358                if status.has_pending_diagnostic_updates {
11359                    Some(*id)
11360                } else {
11361                    None
11362                }
11363            })
11364    }
11365
11366    pub(crate) fn cancel_language_server_work_for_buffers(
11367        &mut self,
11368        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11369        cx: &mut Context<Self>,
11370    ) {
11371        if let Some((client, project_id)) = self.upstream_client() {
11372            let request = client.request(proto::CancelLanguageServerWork {
11373                project_id,
11374                work: Some(proto::cancel_language_server_work::Work::Buffers(
11375                    proto::cancel_language_server_work::Buffers {
11376                        buffer_ids: buffers
11377                            .into_iter()
11378                            .map(|b| b.read(cx).remote_id().to_proto())
11379                            .collect(),
11380                    },
11381                )),
11382            });
11383            cx.background_spawn(request).detach_and_log_err(cx);
11384        } else if let Some(local) = self.as_local() {
11385            let servers = buffers
11386                .into_iter()
11387                .flat_map(|buffer| {
11388                    buffer.update(cx, |buffer, cx| {
11389                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11390                    })
11391                })
11392                .collect::<HashSet<_>>();
11393            for server_id in servers {
11394                self.cancel_language_server_work(server_id, None, cx);
11395            }
11396        }
11397    }
11398
11399    pub(crate) fn cancel_language_server_work(
11400        &mut self,
11401        server_id: LanguageServerId,
11402        token_to_cancel: Option<ProgressToken>,
11403        cx: &mut Context<Self>,
11404    ) {
11405        if let Some(local) = self.as_local() {
11406            let status = self.language_server_statuses.get(&server_id);
11407            let server = local.language_servers.get(&server_id);
11408            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11409            {
11410                for (token, progress) in &status.pending_work {
11411                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11412                        && token != token_to_cancel
11413                    {
11414                        continue;
11415                    }
11416                    if progress.is_cancellable {
11417                        server
11418                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11419                                WorkDoneProgressCancelParams {
11420                                    token: token.to_lsp(),
11421                                },
11422                            )
11423                            .ok();
11424                    }
11425                }
11426            }
11427        } else if let Some((client, project_id)) = self.upstream_client() {
11428            let request = client.request(proto::CancelLanguageServerWork {
11429                project_id,
11430                work: Some(
11431                    proto::cancel_language_server_work::Work::LanguageServerWork(
11432                        proto::cancel_language_server_work::LanguageServerWork {
11433                            language_server_id: server_id.to_proto(),
11434                            token: token_to_cancel.map(|token| token.to_proto()),
11435                        },
11436                    ),
11437                ),
11438            });
11439            cx.background_spawn(request).detach_and_log_err(cx);
11440        }
11441    }
11442
11443    fn register_supplementary_language_server(
11444        &mut self,
11445        id: LanguageServerId,
11446        name: LanguageServerName,
11447        server: Arc<LanguageServer>,
11448        cx: &mut Context<Self>,
11449    ) {
11450        if let Some(local) = self.as_local_mut() {
11451            local
11452                .supplementary_language_servers
11453                .insert(id, (name.clone(), server));
11454            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11455        }
11456    }
11457
11458    fn unregister_supplementary_language_server(
11459        &mut self,
11460        id: LanguageServerId,
11461        cx: &mut Context<Self>,
11462    ) {
11463        if let Some(local) = self.as_local_mut() {
11464            local.supplementary_language_servers.remove(&id);
11465            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11466        }
11467    }
11468
11469    pub(crate) fn supplementary_language_servers(
11470        &self,
11471    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11472        self.as_local().into_iter().flat_map(|local| {
11473            local
11474                .supplementary_language_servers
11475                .iter()
11476                .map(|(id, (name, _))| (*id, name.clone()))
11477        })
11478    }
11479
11480    pub fn language_server_adapter_for_id(
11481        &self,
11482        id: LanguageServerId,
11483    ) -> Option<Arc<CachedLspAdapter>> {
11484        self.as_local()
11485            .and_then(|local| local.language_servers.get(&id))
11486            .and_then(|language_server_state| match language_server_state {
11487                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11488                _ => None,
11489            })
11490    }
11491
11492    pub(super) fn update_local_worktree_language_servers(
11493        &mut self,
11494        worktree_handle: &Entity<Worktree>,
11495        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11496        cx: &mut Context<Self>,
11497    ) {
11498        if changes.is_empty() {
11499            return;
11500        }
11501
11502        let Some(local) = self.as_local() else { return };
11503
11504        local.prettier_store.update(cx, |prettier_store, cx| {
11505            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11506        });
11507
11508        let worktree_id = worktree_handle.read(cx).id();
11509        let mut language_server_ids = local
11510            .language_server_ids
11511            .iter()
11512            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11513            .collect::<Vec<_>>();
11514        language_server_ids.sort();
11515        language_server_ids.dedup();
11516
11517        // let abs_path = worktree_handle.read(cx).abs_path();
11518        for server_id in &language_server_ids {
11519            if let Some(LanguageServerState::Running { server, .. }) =
11520                local.language_servers.get(server_id)
11521                && let Some(watched_paths) = local
11522                    .language_server_watched_paths
11523                    .get(server_id)
11524                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11525            {
11526                let params = lsp::DidChangeWatchedFilesParams {
11527                    changes: changes
11528                        .iter()
11529                        .filter_map(|(path, _, change)| {
11530                            if !watched_paths.is_match(path.as_std_path()) {
11531                                return None;
11532                            }
11533                            let typ = match change {
11534                                PathChange::Loaded => return None,
11535                                PathChange::Added => lsp::FileChangeType::CREATED,
11536                                PathChange::Removed => lsp::FileChangeType::DELETED,
11537                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11538                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11539                            };
11540                            let uri = lsp::Uri::from_file_path(
11541                                worktree_handle.read(cx).absolutize(&path),
11542                            )
11543                            .ok()?;
11544                            Some(lsp::FileEvent { uri, typ })
11545                        })
11546                        .collect(),
11547                };
11548                if !params.changes.is_empty() {
11549                    server
11550                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11551                        .ok();
11552                }
11553            }
11554        }
11555        for (path, _, _) in changes {
11556            if let Some(file_name) = path.file_name()
11557                && local.watched_manifest_filenames.contains(file_name)
11558            {
11559                self.request_workspace_config_refresh();
11560                break;
11561            }
11562        }
11563    }
11564
11565    pub fn wait_for_remote_buffer(
11566        &mut self,
11567        id: BufferId,
11568        cx: &mut Context<Self>,
11569    ) -> Task<Result<Entity<Buffer>>> {
11570        self.buffer_store.update(cx, |buffer_store, cx| {
11571            buffer_store.wait_for_remote_buffer(id, cx)
11572        })
11573    }
11574
11575    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11576        let mut result = proto::Symbol {
11577            language_server_name: symbol.language_server_name.0.to_string(),
11578            source_worktree_id: symbol.source_worktree_id.to_proto(),
11579            language_server_id: symbol.source_language_server_id.to_proto(),
11580            name: symbol.name.clone(),
11581            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11582            start: Some(proto::PointUtf16 {
11583                row: symbol.range.start.0.row,
11584                column: symbol.range.start.0.column,
11585            }),
11586            end: Some(proto::PointUtf16 {
11587                row: symbol.range.end.0.row,
11588                column: symbol.range.end.0.column,
11589            }),
11590            worktree_id: Default::default(),
11591            path: Default::default(),
11592            signature: Default::default(),
11593        };
11594        match &symbol.path {
11595            SymbolLocation::InProject(path) => {
11596                result.worktree_id = path.worktree_id.to_proto();
11597                result.path = path.path.to_proto();
11598            }
11599            SymbolLocation::OutsideProject {
11600                abs_path,
11601                signature,
11602            } => {
11603                result.path = abs_path.to_string_lossy().into_owned();
11604                result.signature = signature.to_vec();
11605            }
11606        }
11607        result
11608    }
11609
11610    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11611        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11612        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11613        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11614
11615        let path = if serialized_symbol.signature.is_empty() {
11616            SymbolLocation::InProject(ProjectPath {
11617                worktree_id,
11618                path: RelPath::from_proto(&serialized_symbol.path)
11619                    .context("invalid symbol path")?,
11620            })
11621        } else {
11622            SymbolLocation::OutsideProject {
11623                abs_path: Path::new(&serialized_symbol.path).into(),
11624                signature: serialized_symbol
11625                    .signature
11626                    .try_into()
11627                    .map_err(|_| anyhow!("invalid signature"))?,
11628            }
11629        };
11630
11631        let start = serialized_symbol.start.context("invalid start")?;
11632        let end = serialized_symbol.end.context("invalid end")?;
11633        Ok(CoreSymbol {
11634            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11635            source_worktree_id,
11636            source_language_server_id: LanguageServerId::from_proto(
11637                serialized_symbol.language_server_id,
11638            ),
11639            path,
11640            name: serialized_symbol.name,
11641            range: Unclipped(PointUtf16::new(start.row, start.column))
11642                ..Unclipped(PointUtf16::new(end.row, end.column)),
11643            kind,
11644        })
11645    }
11646
11647    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11648        let mut serialized_completion = proto::Completion {
11649            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11650            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11651            new_text: completion.new_text.clone(),
11652            ..proto::Completion::default()
11653        };
11654        match &completion.source {
11655            CompletionSource::Lsp {
11656                insert_range,
11657                server_id,
11658                lsp_completion,
11659                lsp_defaults,
11660                resolved,
11661            } => {
11662                let (old_insert_start, old_insert_end) = insert_range
11663                    .as_ref()
11664                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11665                    .unzip();
11666
11667                serialized_completion.old_insert_start = old_insert_start;
11668                serialized_completion.old_insert_end = old_insert_end;
11669                serialized_completion.source = proto::completion::Source::Lsp as i32;
11670                serialized_completion.server_id = server_id.0 as u64;
11671                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11672                serialized_completion.lsp_defaults = lsp_defaults
11673                    .as_deref()
11674                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11675                serialized_completion.resolved = *resolved;
11676            }
11677            CompletionSource::BufferWord {
11678                word_range,
11679                resolved,
11680            } => {
11681                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11682                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11683                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11684                serialized_completion.resolved = *resolved;
11685            }
11686            CompletionSource::Custom => {
11687                serialized_completion.source = proto::completion::Source::Custom as i32;
11688                serialized_completion.resolved = true;
11689            }
11690            CompletionSource::Dap { sort_text } => {
11691                serialized_completion.source = proto::completion::Source::Dap as i32;
11692                serialized_completion.sort_text = Some(sort_text.clone());
11693            }
11694        }
11695
11696        serialized_completion
11697    }
11698
11699    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11700        let old_replace_start = completion
11701            .old_replace_start
11702            .and_then(deserialize_anchor)
11703            .context("invalid old start")?;
11704        let old_replace_end = completion
11705            .old_replace_end
11706            .and_then(deserialize_anchor)
11707            .context("invalid old end")?;
11708        let insert_range = {
11709            match completion.old_insert_start.zip(completion.old_insert_end) {
11710                Some((start, end)) => {
11711                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11712                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11713                    Some(start..end)
11714                }
11715                None => None,
11716            }
11717        };
11718        Ok(CoreCompletion {
11719            replace_range: old_replace_start..old_replace_end,
11720            new_text: completion.new_text,
11721            source: match proto::completion::Source::from_i32(completion.source) {
11722                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11723                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11724                    insert_range,
11725                    server_id: LanguageServerId::from_proto(completion.server_id),
11726                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11727                    lsp_defaults: completion
11728                        .lsp_defaults
11729                        .as_deref()
11730                        .map(serde_json::from_slice)
11731                        .transpose()?,
11732                    resolved: completion.resolved,
11733                },
11734                Some(proto::completion::Source::BufferWord) => {
11735                    let word_range = completion
11736                        .buffer_word_start
11737                        .and_then(deserialize_anchor)
11738                        .context("invalid buffer word start")?
11739                        ..completion
11740                            .buffer_word_end
11741                            .and_then(deserialize_anchor)
11742                            .context("invalid buffer word end")?;
11743                    CompletionSource::BufferWord {
11744                        word_range,
11745                        resolved: completion.resolved,
11746                    }
11747                }
11748                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11749                    sort_text: completion
11750                        .sort_text
11751                        .context("expected sort text to exist")?,
11752                },
11753                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11754            },
11755        })
11756    }
11757
11758    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11759        let (kind, lsp_action) = match &action.lsp_action {
11760            LspAction::Action(code_action) => (
11761                proto::code_action::Kind::Action as i32,
11762                serde_json::to_vec(code_action).unwrap(),
11763            ),
11764            LspAction::Command(command) => (
11765                proto::code_action::Kind::Command as i32,
11766                serde_json::to_vec(command).unwrap(),
11767            ),
11768            LspAction::CodeLens(code_lens) => (
11769                proto::code_action::Kind::CodeLens as i32,
11770                serde_json::to_vec(code_lens).unwrap(),
11771            ),
11772        };
11773
11774        proto::CodeAction {
11775            server_id: action.server_id.0 as u64,
11776            start: Some(serialize_anchor(&action.range.start)),
11777            end: Some(serialize_anchor(&action.range.end)),
11778            lsp_action,
11779            kind,
11780            resolved: action.resolved,
11781        }
11782    }
11783
11784    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11785        let start = action
11786            .start
11787            .and_then(deserialize_anchor)
11788            .context("invalid start")?;
11789        let end = action
11790            .end
11791            .and_then(deserialize_anchor)
11792            .context("invalid end")?;
11793        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11794            Some(proto::code_action::Kind::Action) => {
11795                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11796            }
11797            Some(proto::code_action::Kind::Command) => {
11798                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11799            }
11800            Some(proto::code_action::Kind::CodeLens) => {
11801                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11802            }
11803            None => anyhow::bail!("Unknown action kind {}", action.kind),
11804        };
11805        Ok(CodeAction {
11806            server_id: LanguageServerId(action.server_id as usize),
11807            range: start..end,
11808            resolved: action.resolved,
11809            lsp_action,
11810        })
11811    }
11812
11813    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11814        match &formatting_result {
11815            Ok(_) => self.last_formatting_failure = None,
11816            Err(error) => {
11817                let error_string = format!("{error:#}");
11818                log::error!("Formatting failed: {error_string}");
11819                self.last_formatting_failure
11820                    .replace(error_string.lines().join(" "));
11821            }
11822        }
11823    }
11824
11825    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11826        self.lsp_server_capabilities.remove(&for_server);
11827        for lsp_data in self.lsp_data.values_mut() {
11828            lsp_data.remove_server_data(for_server);
11829        }
11830        if let Some(local) = self.as_local_mut() {
11831            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11832            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11833                buffer_servers.remove(&for_server);
11834            }
11835        }
11836    }
11837
11838    pub fn result_id(
11839        &self,
11840        server_id: LanguageServerId,
11841        buffer_id: BufferId,
11842        cx: &App,
11843    ) -> Option<String> {
11844        let abs_path = self
11845            .buffer_store
11846            .read(cx)
11847            .get(buffer_id)
11848            .and_then(|b| File::from_dyn(b.read(cx).file()))
11849            .map(|f| f.abs_path(cx))?;
11850        self.as_local()?
11851            .buffer_pull_diagnostics_result_ids
11852            .get(&server_id)?
11853            .get(&abs_path)?
11854            .clone()
11855    }
11856
11857    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11858        let Some(local) = self.as_local() else {
11859            return HashMap::default();
11860        };
11861        local
11862            .buffer_pull_diagnostics_result_ids
11863            .get(&server_id)
11864            .into_iter()
11865            .flatten()
11866            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11867            .collect()
11868    }
11869
11870    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11871        if let Some(LanguageServerState::Running {
11872            workspace_diagnostics_refresh_tasks,
11873            ..
11874        }) = self
11875            .as_local_mut()
11876            .and_then(|local| local.language_servers.get_mut(&server_id))
11877        {
11878            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11879                diagnostics.refresh_tx.try_send(()).ok();
11880            }
11881        }
11882    }
11883
11884    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11885        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11886            return;
11887        };
11888        let Some(local) = self.as_local_mut() else {
11889            return;
11890        };
11891
11892        for server_id in buffer.update(cx, |buffer, cx| {
11893            local.language_server_ids_for_buffer(buffer, cx)
11894        }) {
11895            if let Some(LanguageServerState::Running {
11896                workspace_diagnostics_refresh_tasks,
11897                ..
11898            }) = local.language_servers.get_mut(&server_id)
11899            {
11900                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11901                    diagnostics.refresh_tx.try_send(()).ok();
11902                }
11903            }
11904        }
11905    }
11906
11907    fn apply_workspace_diagnostic_report(
11908        &mut self,
11909        server_id: LanguageServerId,
11910        report: lsp::WorkspaceDiagnosticReportResult,
11911        cx: &mut Context<Self>,
11912    ) {
11913        let workspace_diagnostics =
11914            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11915        let mut unchanged_buffers = HashSet::default();
11916        let mut changed_buffers = HashSet::default();
11917        let workspace_diagnostics_updates = workspace_diagnostics
11918            .into_iter()
11919            .filter_map(
11920                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11921                    LspPullDiagnostics::Response {
11922                        server_id,
11923                        uri,
11924                        diagnostics,
11925                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11926                    LspPullDiagnostics::Default => None,
11927                },
11928            )
11929            .fold(
11930                HashMap::default(),
11931                |mut acc, (server_id, uri, diagnostics, version)| {
11932                    let (result_id, diagnostics) = match diagnostics {
11933                        PulledDiagnostics::Unchanged { result_id } => {
11934                            unchanged_buffers.insert(uri.clone());
11935                            (Some(result_id), Vec::new())
11936                        }
11937                        PulledDiagnostics::Changed {
11938                            result_id,
11939                            diagnostics,
11940                        } => {
11941                            changed_buffers.insert(uri.clone());
11942                            (result_id, diagnostics)
11943                        }
11944                    };
11945                    let disk_based_sources = Cow::Owned(
11946                        self.language_server_adapter_for_id(server_id)
11947                            .as_ref()
11948                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11949                            .unwrap_or(&[])
11950                            .to_vec(),
11951                    );
11952                    acc.entry(server_id)
11953                        .or_insert_with(Vec::new)
11954                        .push(DocumentDiagnosticsUpdate {
11955                            server_id,
11956                            diagnostics: lsp::PublishDiagnosticsParams {
11957                                uri,
11958                                diagnostics,
11959                                version,
11960                            },
11961                            result_id,
11962                            disk_based_sources,
11963                        });
11964                    acc
11965                },
11966            );
11967
11968        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11969            self.merge_lsp_diagnostics(
11970                DiagnosticSourceKind::Pulled,
11971                diagnostic_updates,
11972                |buffer, old_diagnostic, cx| {
11973                    File::from_dyn(buffer.file())
11974                        .and_then(|file| {
11975                            let abs_path = file.as_local()?.abs_path(cx);
11976                            lsp::Uri::from_file_path(abs_path).ok()
11977                        })
11978                        .is_none_or(|buffer_uri| {
11979                            unchanged_buffers.contains(&buffer_uri)
11980                                || match old_diagnostic.source_kind {
11981                                    DiagnosticSourceKind::Pulled => {
11982                                        !changed_buffers.contains(&buffer_uri)
11983                                    }
11984                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11985                                        true
11986                                    }
11987                                }
11988                        })
11989                },
11990                cx,
11991            )
11992            .log_err();
11993        }
11994    }
11995
11996    fn register_server_capabilities(
11997        &mut self,
11998        server_id: LanguageServerId,
11999        params: lsp::RegistrationParams,
12000        cx: &mut Context<Self>,
12001    ) -> anyhow::Result<()> {
12002        let server = self
12003            .language_server_for_id(server_id)
12004            .with_context(|| format!("no server {server_id} found"))?;
12005        for reg in params.registrations {
12006            match reg.method.as_str() {
12007                "workspace/didChangeWatchedFiles" => {
12008                    if let Some(options) = reg.register_options {
12009                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12010                            let caps = serde_json::from_value(options)?;
12011                            local_lsp_store
12012                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12013                            true
12014                        } else {
12015                            false
12016                        };
12017                        if notify {
12018                            notify_server_capabilities_updated(&server, cx);
12019                        }
12020                    }
12021                }
12022                "workspace/didChangeConfiguration" => {
12023                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12024                }
12025                "workspace/didChangeWorkspaceFolders" => {
12026                    // In this case register options is an empty object, we can ignore it
12027                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12028                        supported: Some(true),
12029                        change_notifications: Some(OneOf::Right(reg.id)),
12030                    };
12031                    server.update_capabilities(|capabilities| {
12032                        capabilities
12033                            .workspace
12034                            .get_or_insert_default()
12035                            .workspace_folders = Some(caps);
12036                    });
12037                    notify_server_capabilities_updated(&server, cx);
12038                }
12039                "workspace/symbol" => {
12040                    let options = parse_register_capabilities(reg)?;
12041                    server.update_capabilities(|capabilities| {
12042                        capabilities.workspace_symbol_provider = Some(options);
12043                    });
12044                    notify_server_capabilities_updated(&server, cx);
12045                }
12046                "workspace/fileOperations" => {
12047                    if let Some(options) = reg.register_options {
12048                        let caps = serde_json::from_value(options)?;
12049                        server.update_capabilities(|capabilities| {
12050                            capabilities
12051                                .workspace
12052                                .get_or_insert_default()
12053                                .file_operations = Some(caps);
12054                        });
12055                        notify_server_capabilities_updated(&server, cx);
12056                    }
12057                }
12058                "workspace/executeCommand" => {
12059                    if let Some(options) = reg.register_options {
12060                        let options = serde_json::from_value(options)?;
12061                        server.update_capabilities(|capabilities| {
12062                            capabilities.execute_command_provider = Some(options);
12063                        });
12064                        notify_server_capabilities_updated(&server, cx);
12065                    }
12066                }
12067                "textDocument/rangeFormatting" => {
12068                    let options = parse_register_capabilities(reg)?;
12069                    server.update_capabilities(|capabilities| {
12070                        capabilities.document_range_formatting_provider = Some(options);
12071                    });
12072                    notify_server_capabilities_updated(&server, cx);
12073                }
12074                "textDocument/onTypeFormatting" => {
12075                    if let Some(options) = reg
12076                        .register_options
12077                        .map(serde_json::from_value)
12078                        .transpose()?
12079                    {
12080                        server.update_capabilities(|capabilities| {
12081                            capabilities.document_on_type_formatting_provider = Some(options);
12082                        });
12083                        notify_server_capabilities_updated(&server, cx);
12084                    }
12085                }
12086                "textDocument/formatting" => {
12087                    let options = parse_register_capabilities(reg)?;
12088                    server.update_capabilities(|capabilities| {
12089                        capabilities.document_formatting_provider = Some(options);
12090                    });
12091                    notify_server_capabilities_updated(&server, cx);
12092                }
12093                "textDocument/rename" => {
12094                    let options = parse_register_capabilities(reg)?;
12095                    server.update_capabilities(|capabilities| {
12096                        capabilities.rename_provider = Some(options);
12097                    });
12098                    notify_server_capabilities_updated(&server, cx);
12099                }
12100                "textDocument/inlayHint" => {
12101                    let options = parse_register_capabilities(reg)?;
12102                    server.update_capabilities(|capabilities| {
12103                        capabilities.inlay_hint_provider = Some(options);
12104                    });
12105                    notify_server_capabilities_updated(&server, cx);
12106                }
12107                "textDocument/documentSymbol" => {
12108                    let options = parse_register_capabilities(reg)?;
12109                    server.update_capabilities(|capabilities| {
12110                        capabilities.document_symbol_provider = Some(options);
12111                    });
12112                    notify_server_capabilities_updated(&server, cx);
12113                }
12114                "textDocument/codeAction" => {
12115                    let options = parse_register_capabilities(reg)?;
12116                    let provider = match options {
12117                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12118                        OneOf::Right(caps) => caps,
12119                    };
12120                    server.update_capabilities(|capabilities| {
12121                        capabilities.code_action_provider = Some(provider);
12122                    });
12123                    notify_server_capabilities_updated(&server, cx);
12124                }
12125                "textDocument/definition" => {
12126                    let options = parse_register_capabilities(reg)?;
12127                    server.update_capabilities(|capabilities| {
12128                        capabilities.definition_provider = Some(options);
12129                    });
12130                    notify_server_capabilities_updated(&server, cx);
12131                }
12132                "textDocument/completion" => {
12133                    if let Some(caps) = reg
12134                        .register_options
12135                        .map(serde_json::from_value::<CompletionOptions>)
12136                        .transpose()?
12137                    {
12138                        server.update_capabilities(|capabilities| {
12139                            capabilities.completion_provider = Some(caps.clone());
12140                        });
12141
12142                        if let Some(local) = self.as_local() {
12143                            let mut buffers_with_language_server = Vec::new();
12144                            for handle in self.buffer_store.read(cx).buffers() {
12145                                let buffer_id = handle.read(cx).remote_id();
12146                                if local
12147                                    .buffers_opened_in_servers
12148                                    .get(&buffer_id)
12149                                    .filter(|s| s.contains(&server_id))
12150                                    .is_some()
12151                                {
12152                                    buffers_with_language_server.push(handle);
12153                                }
12154                            }
12155                            let triggers = caps
12156                                .trigger_characters
12157                                .unwrap_or_default()
12158                                .into_iter()
12159                                .collect::<BTreeSet<_>>();
12160                            for handle in buffers_with_language_server {
12161                                let triggers = triggers.clone();
12162                                let _ = handle.update(cx, move |buffer, cx| {
12163                                    buffer.set_completion_triggers(server_id, triggers, cx);
12164                                });
12165                            }
12166                        }
12167                        notify_server_capabilities_updated(&server, cx);
12168                    }
12169                }
12170                "textDocument/hover" => {
12171                    let options = parse_register_capabilities(reg)?;
12172                    let provider = match options {
12173                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12174                        OneOf::Right(caps) => caps,
12175                    };
12176                    server.update_capabilities(|capabilities| {
12177                        capabilities.hover_provider = Some(provider);
12178                    });
12179                    notify_server_capabilities_updated(&server, cx);
12180                }
12181                "textDocument/signatureHelp" => {
12182                    if let Some(caps) = reg
12183                        .register_options
12184                        .map(serde_json::from_value)
12185                        .transpose()?
12186                    {
12187                        server.update_capabilities(|capabilities| {
12188                            capabilities.signature_help_provider = Some(caps);
12189                        });
12190                        notify_server_capabilities_updated(&server, cx);
12191                    }
12192                }
12193                "textDocument/didChange" => {
12194                    if let Some(sync_kind) = reg
12195                        .register_options
12196                        .and_then(|opts| opts.get("syncKind").cloned())
12197                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12198                        .transpose()?
12199                    {
12200                        server.update_capabilities(|capabilities| {
12201                            let mut sync_options =
12202                                Self::take_text_document_sync_options(capabilities);
12203                            sync_options.change = Some(sync_kind);
12204                            capabilities.text_document_sync =
12205                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12206                        });
12207                        notify_server_capabilities_updated(&server, cx);
12208                    }
12209                }
12210                "textDocument/didSave" => {
12211                    if let Some(include_text) = reg
12212                        .register_options
12213                        .map(|opts| {
12214                            let transpose = opts
12215                                .get("includeText")
12216                                .cloned()
12217                                .map(serde_json::from_value::<Option<bool>>)
12218                                .transpose();
12219                            match transpose {
12220                                Ok(value) => Ok(value.flatten()),
12221                                Err(e) => Err(e),
12222                            }
12223                        })
12224                        .transpose()?
12225                    {
12226                        server.update_capabilities(|capabilities| {
12227                            let mut sync_options =
12228                                Self::take_text_document_sync_options(capabilities);
12229                            sync_options.save =
12230                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12231                                    include_text,
12232                                }));
12233                            capabilities.text_document_sync =
12234                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12235                        });
12236                        notify_server_capabilities_updated(&server, cx);
12237                    }
12238                }
12239                "textDocument/codeLens" => {
12240                    if let Some(caps) = reg
12241                        .register_options
12242                        .map(serde_json::from_value)
12243                        .transpose()?
12244                    {
12245                        server.update_capabilities(|capabilities| {
12246                            capabilities.code_lens_provider = Some(caps);
12247                        });
12248                        notify_server_capabilities_updated(&server, cx);
12249                    }
12250                }
12251                "textDocument/diagnostic" => {
12252                    if let Some(caps) = reg
12253                        .register_options
12254                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12255                        .transpose()?
12256                    {
12257                        let local = self
12258                            .as_local_mut()
12259                            .context("Expected LSP Store to be local")?;
12260                        let state = local
12261                            .language_servers
12262                            .get_mut(&server_id)
12263                            .context("Could not obtain Language Servers state")?;
12264                        local
12265                            .language_server_dynamic_registrations
12266                            .entry(server_id)
12267                            .or_default()
12268                            .diagnostics
12269                            .insert(Some(reg.id.clone()), caps.clone());
12270
12271                        if let LanguageServerState::Running {
12272                            workspace_diagnostics_refresh_tasks,
12273                            ..
12274                        } = state
12275                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12276                                Some(reg.id.clone()),
12277                                caps.clone(),
12278                                server.clone(),
12279                                cx,
12280                            )
12281                        {
12282                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12283                        }
12284
12285                        let mut did_update_caps = false;
12286                        server.update_capabilities(|capabilities| {
12287                            if capabilities.diagnostic_provider.as_ref().is_none_or(
12288                                |current_caps| {
12289                                    let supports_workspace_diagnostics =
12290                                        |capabilities: &DiagnosticServerCapabilities| {
12291                                            match capabilities {
12292                                            DiagnosticServerCapabilities::Options(
12293                                                diagnostic_options,
12294                                            ) => diagnostic_options.workspace_diagnostics,
12295                                            DiagnosticServerCapabilities::RegistrationOptions(
12296                                                diagnostic_registration_options,
12297                                            ) => {
12298                                                diagnostic_registration_options
12299                                                    .diagnostic_options
12300                                                    .workspace_diagnostics
12301                                            }
12302                                        }
12303                                        };
12304                                    // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12305                                    // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12306                                    // as it'll think that they're not supported.
12307                                    // If we did not support any workspace diagnostics up to this point but now do, let's update.
12308                                    !supports_workspace_diagnostics(current_caps)
12309                                        & supports_workspace_diagnostics(&caps)
12310                                },
12311                            ) {
12312                                did_update_caps = true;
12313                                capabilities.diagnostic_provider = Some(caps);
12314                            }
12315                        });
12316                        if did_update_caps {
12317                            notify_server_capabilities_updated(&server, cx);
12318                        }
12319                    }
12320                }
12321                "textDocument/documentColor" => {
12322                    let options = parse_register_capabilities(reg)?;
12323                    let provider = match options {
12324                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12325                        OneOf::Right(caps) => caps,
12326                    };
12327                    server.update_capabilities(|capabilities| {
12328                        capabilities.color_provider = Some(provider);
12329                    });
12330                    notify_server_capabilities_updated(&server, cx);
12331                }
12332                _ => log::warn!("unhandled capability registration: {reg:?}"),
12333            }
12334        }
12335
12336        Ok(())
12337    }
12338
12339    fn unregister_server_capabilities(
12340        &mut self,
12341        server_id: LanguageServerId,
12342        params: lsp::UnregistrationParams,
12343        cx: &mut Context<Self>,
12344    ) -> anyhow::Result<()> {
12345        let server = self
12346            .language_server_for_id(server_id)
12347            .with_context(|| format!("no server {server_id} found"))?;
12348        for unreg in params.unregisterations.iter() {
12349            match unreg.method.as_str() {
12350                "workspace/didChangeWatchedFiles" => {
12351                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12352                        local_lsp_store
12353                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12354                        true
12355                    } else {
12356                        false
12357                    };
12358                    if notify {
12359                        notify_server_capabilities_updated(&server, cx);
12360                    }
12361                }
12362                "workspace/didChangeConfiguration" => {
12363                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12364                }
12365                "workspace/didChangeWorkspaceFolders" => {
12366                    server.update_capabilities(|capabilities| {
12367                        capabilities
12368                            .workspace
12369                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12370                                workspace_folders: None,
12371                                file_operations: None,
12372                            })
12373                            .workspace_folders = None;
12374                    });
12375                    notify_server_capabilities_updated(&server, cx);
12376                }
12377                "workspace/symbol" => {
12378                    server.update_capabilities(|capabilities| {
12379                        capabilities.workspace_symbol_provider = None
12380                    });
12381                    notify_server_capabilities_updated(&server, cx);
12382                }
12383                "workspace/fileOperations" => {
12384                    server.update_capabilities(|capabilities| {
12385                        capabilities
12386                            .workspace
12387                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12388                                workspace_folders: None,
12389                                file_operations: None,
12390                            })
12391                            .file_operations = None;
12392                    });
12393                    notify_server_capabilities_updated(&server, cx);
12394                }
12395                "workspace/executeCommand" => {
12396                    server.update_capabilities(|capabilities| {
12397                        capabilities.execute_command_provider = None;
12398                    });
12399                    notify_server_capabilities_updated(&server, cx);
12400                }
12401                "textDocument/rangeFormatting" => {
12402                    server.update_capabilities(|capabilities| {
12403                        capabilities.document_range_formatting_provider = None
12404                    });
12405                    notify_server_capabilities_updated(&server, cx);
12406                }
12407                "textDocument/onTypeFormatting" => {
12408                    server.update_capabilities(|capabilities| {
12409                        capabilities.document_on_type_formatting_provider = None;
12410                    });
12411                    notify_server_capabilities_updated(&server, cx);
12412                }
12413                "textDocument/formatting" => {
12414                    server.update_capabilities(|capabilities| {
12415                        capabilities.document_formatting_provider = None;
12416                    });
12417                    notify_server_capabilities_updated(&server, cx);
12418                }
12419                "textDocument/rename" => {
12420                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12421                    notify_server_capabilities_updated(&server, cx);
12422                }
12423                "textDocument/codeAction" => {
12424                    server.update_capabilities(|capabilities| {
12425                        capabilities.code_action_provider = None;
12426                    });
12427                    notify_server_capabilities_updated(&server, cx);
12428                }
12429                "textDocument/definition" => {
12430                    server.update_capabilities(|capabilities| {
12431                        capabilities.definition_provider = None;
12432                    });
12433                    notify_server_capabilities_updated(&server, cx);
12434                }
12435                "textDocument/completion" => {
12436                    server.update_capabilities(|capabilities| {
12437                        capabilities.completion_provider = None;
12438                    });
12439                    notify_server_capabilities_updated(&server, cx);
12440                }
12441                "textDocument/hover" => {
12442                    server.update_capabilities(|capabilities| {
12443                        capabilities.hover_provider = None;
12444                    });
12445                    notify_server_capabilities_updated(&server, cx);
12446                }
12447                "textDocument/signatureHelp" => {
12448                    server.update_capabilities(|capabilities| {
12449                        capabilities.signature_help_provider = None;
12450                    });
12451                    notify_server_capabilities_updated(&server, cx);
12452                }
12453                "textDocument/didChange" => {
12454                    server.update_capabilities(|capabilities| {
12455                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12456                        sync_options.change = None;
12457                        capabilities.text_document_sync =
12458                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12459                    });
12460                    notify_server_capabilities_updated(&server, cx);
12461                }
12462                "textDocument/didSave" => {
12463                    server.update_capabilities(|capabilities| {
12464                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12465                        sync_options.save = None;
12466                        capabilities.text_document_sync =
12467                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12468                    });
12469                    notify_server_capabilities_updated(&server, cx);
12470                }
12471                "textDocument/codeLens" => {
12472                    server.update_capabilities(|capabilities| {
12473                        capabilities.code_lens_provider = None;
12474                    });
12475                    notify_server_capabilities_updated(&server, cx);
12476                }
12477                "textDocument/diagnostic" => {
12478                    let local = self
12479                        .as_local_mut()
12480                        .context("Expected LSP Store to be local")?;
12481
12482                    let state = local
12483                        .language_servers
12484                        .get_mut(&server_id)
12485                        .context("Could not obtain Language Servers state")?;
12486                    let options = local
12487                        .language_server_dynamic_registrations
12488                        .get_mut(&server_id)
12489                        .with_context(|| {
12490                            format!("Expected dynamic registration to exist for server {server_id}")
12491                        })?.diagnostics
12492                        .remove(&Some(unreg.id.clone()))
12493                        .with_context(|| format!(
12494                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12495                            unreg.id)
12496                        )?;
12497
12498                    let mut has_any_diagnostic_providers_still = true;
12499                    if let Some(identifier) = diagnostic_identifier(&options)
12500                        && let LanguageServerState::Running {
12501                            workspace_diagnostics_refresh_tasks,
12502                            ..
12503                        } = state
12504                    {
12505                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12506                        has_any_diagnostic_providers_still =
12507                            !workspace_diagnostics_refresh_tasks.is_empty();
12508                    }
12509
12510                    if !has_any_diagnostic_providers_still {
12511                        server.update_capabilities(|capabilities| {
12512                            debug_assert!(capabilities.diagnostic_provider.is_some());
12513                            capabilities.diagnostic_provider = None;
12514                        });
12515                    }
12516
12517                    notify_server_capabilities_updated(&server, cx);
12518                }
12519                "textDocument/documentColor" => {
12520                    server.update_capabilities(|capabilities| {
12521                        capabilities.color_provider = None;
12522                    });
12523                    notify_server_capabilities_updated(&server, cx);
12524                }
12525                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12526            }
12527        }
12528
12529        Ok(())
12530    }
12531
12532    async fn deduplicate_range_based_lsp_requests<T>(
12533        lsp_store: &Entity<Self>,
12534        server_id: Option<LanguageServerId>,
12535        lsp_request_id: LspRequestId,
12536        proto_request: &T::ProtoRequest,
12537        range: Range<Anchor>,
12538        cx: &mut AsyncApp,
12539    ) -> Result<()>
12540    where
12541        T: LspCommand,
12542        T::ProtoRequest: proto::LspRequestMessage,
12543    {
12544        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12545        let version = deserialize_version(proto_request.buffer_version());
12546        let buffer = lsp_store.update(cx, |this, cx| {
12547            this.buffer_store.read(cx).get_existing(buffer_id)
12548        })??;
12549        buffer
12550            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12551            .await?;
12552        lsp_store.update(cx, |lsp_store, cx| {
12553            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12554            let chunks_queried_for = lsp_data
12555                .inlay_hints
12556                .applicable_chunks(&[range])
12557                .collect::<Vec<_>>();
12558            match chunks_queried_for.as_slice() {
12559                &[chunk] => {
12560                    let key = LspKey {
12561                        request_type: TypeId::of::<T>(),
12562                        server_queried: server_id,
12563                    };
12564                    let previous_request = lsp_data
12565                        .chunk_lsp_requests
12566                        .entry(key)
12567                        .or_default()
12568                        .insert(chunk, lsp_request_id);
12569                    if let Some((previous_request, running_requests)) =
12570                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12571                    {
12572                        running_requests.remove(&previous_request);
12573                    }
12574                }
12575                _ambiguous_chunks => {
12576                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12577                    // there, a buffer version-based check will be performed and outdated requests discarded.
12578                }
12579            }
12580            anyhow::Ok(())
12581        })??;
12582
12583        Ok(())
12584    }
12585
12586    async fn query_lsp_locally<T>(
12587        lsp_store: Entity<Self>,
12588        for_server_id: Option<LanguageServerId>,
12589        sender_id: proto::PeerId,
12590        lsp_request_id: LspRequestId,
12591        proto_request: T::ProtoRequest,
12592        position: Option<Anchor>,
12593        cx: &mut AsyncApp,
12594    ) -> Result<()>
12595    where
12596        T: LspCommand + Clone,
12597        T::ProtoRequest: proto::LspRequestMessage,
12598        <T::ProtoRequest as proto::RequestMessage>::Response:
12599            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12600    {
12601        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12602        let version = deserialize_version(proto_request.buffer_version());
12603        let buffer = lsp_store.update(cx, |this, cx| {
12604            this.buffer_store.read(cx).get_existing(buffer_id)
12605        })??;
12606        buffer
12607            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12608            .await?;
12609        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12610        let request =
12611            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12612        let key = LspKey {
12613            request_type: TypeId::of::<T>(),
12614            server_queried: for_server_id,
12615        };
12616        lsp_store.update(cx, |lsp_store, cx| {
12617            let request_task = match for_server_id {
12618                Some(server_id) => {
12619                    let server_task = lsp_store.request_lsp(
12620                        buffer.clone(),
12621                        LanguageServerToQuery::Other(server_id),
12622                        request.clone(),
12623                        cx,
12624                    );
12625                    cx.background_spawn(async move {
12626                        let mut responses = Vec::new();
12627                        match server_task.await {
12628                            Ok(response) => responses.push((server_id, response)),
12629                            // rust-analyzer likes to error with this when its still loading up
12630                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12631                            Err(e) => log::error!(
12632                                "Error handling response for request {request:?}: {e:#}"
12633                            ),
12634                        }
12635                        responses
12636                    })
12637                }
12638                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12639            };
12640            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12641            if T::ProtoRequest::stop_previous_requests() {
12642                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12643                    lsp_requests.clear();
12644                }
12645            }
12646            lsp_data.lsp_requests.entry(key).or_default().insert(
12647                lsp_request_id,
12648                cx.spawn(async move |lsp_store, cx| {
12649                    let response = request_task.await;
12650                    lsp_store
12651                        .update(cx, |lsp_store, cx| {
12652                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12653                            {
12654                                let response = response
12655                                    .into_iter()
12656                                    .map(|(server_id, response)| {
12657                                        (
12658                                            server_id.to_proto(),
12659                                            T::response_to_proto(
12660                                                response,
12661                                                lsp_store,
12662                                                sender_id,
12663                                                &buffer_version,
12664                                                cx,
12665                                            )
12666                                            .into(),
12667                                        )
12668                                    })
12669                                    .collect::<HashMap<_, _>>();
12670                                match client.send_lsp_response::<T::ProtoRequest>(
12671                                    project_id,
12672                                    lsp_request_id,
12673                                    response,
12674                                ) {
12675                                    Ok(()) => {}
12676                                    Err(e) => {
12677                                        log::error!("Failed to send LSP response: {e:#}",)
12678                                    }
12679                                }
12680                            }
12681                        })
12682                        .ok();
12683                }),
12684            );
12685        })?;
12686        Ok(())
12687    }
12688
12689    fn take_text_document_sync_options(
12690        capabilities: &mut lsp::ServerCapabilities,
12691    ) -> lsp::TextDocumentSyncOptions {
12692        match capabilities.text_document_sync.take() {
12693            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12694            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12695                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12696                sync_options.change = Some(sync_kind);
12697                sync_options
12698            }
12699            None => lsp::TextDocumentSyncOptions::default(),
12700        }
12701    }
12702
12703    #[cfg(any(test, feature = "test-support"))]
12704    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12705        Some(
12706            self.lsp_data
12707                .get_mut(&buffer_id)?
12708                .code_lens
12709                .take()?
12710                .update
12711                .take()?
12712                .1,
12713        )
12714    }
12715
12716    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12717        self.downstream_client.clone()
12718    }
12719
12720    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12721        self.worktree_store.clone()
12722    }
12723
12724    /// Gets what's stored in the LSP data for the given buffer.
12725    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12726        self.lsp_data.get_mut(&buffer_id)
12727    }
12728
12729    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12730    /// new [`BufferLspData`] will be created to replace the previous state.
12731    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12732        let (buffer_id, buffer_version) =
12733            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12734        let lsp_data = self
12735            .lsp_data
12736            .entry(buffer_id)
12737            .or_insert_with(|| BufferLspData::new(buffer, cx));
12738        if buffer_version.changed_since(&lsp_data.buffer_version) {
12739            *lsp_data = BufferLspData::new(buffer, cx);
12740        }
12741        lsp_data
12742    }
12743}
12744
12745// Registration with registerOptions as null, should fallback to true.
12746// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12747fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12748    reg: lsp::Registration,
12749) -> Result<OneOf<bool, T>> {
12750    Ok(match reg.register_options {
12751        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12752        None => OneOf::Left(true),
12753    })
12754}
12755
12756fn subscribe_to_binary_statuses(
12757    languages: &Arc<LanguageRegistry>,
12758    cx: &mut Context<'_, LspStore>,
12759) -> Task<()> {
12760    let mut server_statuses = languages.language_server_binary_statuses();
12761    cx.spawn(async move |lsp_store, cx| {
12762        while let Some((server_name, binary_status)) = server_statuses.next().await {
12763            if lsp_store
12764                .update(cx, |_, cx| {
12765                    let mut message = None;
12766                    let binary_status = match binary_status {
12767                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12768                        BinaryStatus::CheckingForUpdate => {
12769                            proto::ServerBinaryStatus::CheckingForUpdate
12770                        }
12771                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12772                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12773                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12774                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12775                        BinaryStatus::Failed { error } => {
12776                            message = Some(error);
12777                            proto::ServerBinaryStatus::Failed
12778                        }
12779                    };
12780                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12781                        // Binary updates are about the binary that might not have any language server id at that point.
12782                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12783                        language_server_id: LanguageServerId(0),
12784                        name: Some(server_name),
12785                        message: proto::update_language_server::Variant::StatusUpdate(
12786                            proto::StatusUpdate {
12787                                message,
12788                                status: Some(proto::status_update::Status::Binary(
12789                                    binary_status as i32,
12790                                )),
12791                            },
12792                        ),
12793                    });
12794                })
12795                .is_err()
12796            {
12797                break;
12798            }
12799        }
12800    })
12801}
12802
12803fn lsp_workspace_diagnostics_refresh(
12804    registration_id: Option<String>,
12805    options: DiagnosticServerCapabilities,
12806    server: Arc<LanguageServer>,
12807    cx: &mut Context<'_, LspStore>,
12808) -> Option<WorkspaceRefreshTask> {
12809    let identifier = diagnostic_identifier(&options)?;
12810
12811    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12812    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12813    refresh_tx.try_send(()).ok();
12814
12815    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12816        let mut attempts = 0;
12817        let max_attempts = 50;
12818        let mut requests = 0;
12819
12820        loop {
12821            let Some(()) = refresh_rx.recv().await else {
12822                return;
12823            };
12824
12825            'request: loop {
12826                requests += 1;
12827                if attempts > max_attempts {
12828                    log::error!(
12829                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12830                    );
12831                    return;
12832                }
12833                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12834                cx.background_executor()
12835                    .timer(Duration::from_millis(backoff_millis))
12836                    .await;
12837                attempts += 1;
12838
12839                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12840                    lsp_store
12841                        .all_result_ids(server.server_id())
12842                        .into_iter()
12843                        .filter_map(|(abs_path, result_id)| {
12844                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12845                            Some(lsp::PreviousResultId {
12846                                uri,
12847                                value: result_id,
12848                            })
12849                        })
12850                        .collect()
12851                }) else {
12852                    return;
12853                };
12854
12855                let token = if let Some(identifier) = &registration_id {
12856                    format!(
12857                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12858                        server.server_id(),
12859                    )
12860                } else {
12861                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12862                };
12863
12864                progress_rx.try_recv().ok();
12865                let timer =
12866                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12867                let progress = pin!(progress_rx.recv().fuse());
12868                let response_result = server
12869                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12870                        lsp::WorkspaceDiagnosticParams {
12871                            previous_result_ids,
12872                            identifier: identifier.clone(),
12873                            work_done_progress_params: Default::default(),
12874                            partial_result_params: lsp::PartialResultParams {
12875                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12876                            },
12877                        },
12878                        select(timer, progress).then(|either| match either {
12879                            Either::Left((message, ..)) => ready(message).left_future(),
12880                            Either::Right(..) => pending::<String>().right_future(),
12881                        }),
12882                    )
12883                    .await;
12884
12885                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12886                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12887                match response_result {
12888                    ConnectionResult::Timeout => {
12889                        log::error!("Timeout during workspace diagnostics pull");
12890                        continue 'request;
12891                    }
12892                    ConnectionResult::ConnectionReset => {
12893                        log::error!("Server closed a workspace diagnostics pull request");
12894                        continue 'request;
12895                    }
12896                    ConnectionResult::Result(Err(e)) => {
12897                        log::error!("Error during workspace diagnostics pull: {e:#}");
12898                        break 'request;
12899                    }
12900                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12901                        attempts = 0;
12902                        if lsp_store
12903                            .update(cx, |lsp_store, cx| {
12904                                lsp_store.apply_workspace_diagnostic_report(
12905                                    server.server_id(),
12906                                    pulled_diagnostics,
12907                                    cx,
12908                                )
12909                            })
12910                            .is_err()
12911                        {
12912                            return;
12913                        }
12914                        break 'request;
12915                    }
12916                }
12917            }
12918        }
12919    });
12920
12921    Some(WorkspaceRefreshTask {
12922        refresh_tx,
12923        progress_tx,
12924        task: workspace_query_language_server,
12925    })
12926}
12927
12928fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12929    match &options {
12930        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12931            if !diagnostic_options.workspace_diagnostics {
12932                return None;
12933            }
12934            Some(diagnostic_options.identifier.clone())
12935        }
12936        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12937            let diagnostic_options = &registration_options.diagnostic_options;
12938            if !diagnostic_options.workspace_diagnostics {
12939                return None;
12940            }
12941            Some(diagnostic_options.identifier.clone())
12942        }
12943    }
12944}
12945
12946fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12947    let CompletionSource::BufferWord {
12948        word_range,
12949        resolved,
12950    } = &mut completion.source
12951    else {
12952        return;
12953    };
12954    if *resolved {
12955        return;
12956    }
12957
12958    if completion.new_text
12959        != snapshot
12960            .text_for_range(word_range.clone())
12961            .collect::<String>()
12962    {
12963        return;
12964    }
12965
12966    let mut offset = 0;
12967    for chunk in snapshot.chunks(word_range.clone(), true) {
12968        let end_offset = offset + chunk.text.len();
12969        if let Some(highlight_id) = chunk.syntax_highlight_id {
12970            completion
12971                .label
12972                .runs
12973                .push((offset..end_offset, highlight_id));
12974        }
12975        offset = end_offset;
12976    }
12977    *resolved = true;
12978}
12979
12980impl EventEmitter<LspStoreEvent> for LspStore {}
12981
12982fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12983    hover
12984        .contents
12985        .retain(|hover_block| !hover_block.text.trim().is_empty());
12986    if hover.contents.is_empty() {
12987        None
12988    } else {
12989        Some(hover)
12990    }
12991}
12992
12993async fn populate_labels_for_completions(
12994    new_completions: Vec<CoreCompletion>,
12995    language: Option<Arc<Language>>,
12996    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12997) -> Vec<Completion> {
12998    let lsp_completions = new_completions
12999        .iter()
13000        .filter_map(|new_completion| {
13001            new_completion
13002                .source
13003                .lsp_completion(true)
13004                .map(|lsp_completion| lsp_completion.into_owned())
13005        })
13006        .collect::<Vec<_>>();
13007
13008    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13009        lsp_adapter
13010            .labels_for_completions(&lsp_completions, language)
13011            .await
13012            .log_err()
13013            .unwrap_or_default()
13014    } else {
13015        Vec::new()
13016    }
13017    .into_iter()
13018    .fuse();
13019
13020    let mut completions = Vec::new();
13021    for completion in new_completions {
13022        match completion.source.lsp_completion(true) {
13023            Some(lsp_completion) => {
13024                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13025
13026                let mut label = labels.next().flatten().unwrap_or_else(|| {
13027                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13028                });
13029                ensure_uniform_list_compatible_label(&mut label);
13030                completions.push(Completion {
13031                    label,
13032                    documentation,
13033                    replace_range: completion.replace_range,
13034                    new_text: completion.new_text,
13035                    insert_text_mode: lsp_completion.insert_text_mode,
13036                    source: completion.source,
13037                    icon_path: None,
13038                    confirm: None,
13039                    match_start: None,
13040                    snippet_deduplication_key: None,
13041                });
13042            }
13043            None => {
13044                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13045                ensure_uniform_list_compatible_label(&mut label);
13046                completions.push(Completion {
13047                    label,
13048                    documentation: None,
13049                    replace_range: completion.replace_range,
13050                    new_text: completion.new_text,
13051                    source: completion.source,
13052                    insert_text_mode: None,
13053                    icon_path: None,
13054                    confirm: None,
13055                    match_start: None,
13056                    snippet_deduplication_key: None,
13057                });
13058            }
13059        }
13060    }
13061    completions
13062}
13063
13064#[derive(Debug)]
13065pub enum LanguageServerToQuery {
13066    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13067    FirstCapable,
13068    /// Query a specific language server.
13069    Other(LanguageServerId),
13070}
13071
13072#[derive(Default)]
13073struct RenamePathsWatchedForServer {
13074    did_rename: Vec<RenameActionPredicate>,
13075    will_rename: Vec<RenameActionPredicate>,
13076}
13077
13078impl RenamePathsWatchedForServer {
13079    fn with_did_rename_patterns(
13080        mut self,
13081        did_rename: Option<&FileOperationRegistrationOptions>,
13082    ) -> Self {
13083        if let Some(did_rename) = did_rename {
13084            self.did_rename = did_rename
13085                .filters
13086                .iter()
13087                .filter_map(|filter| filter.try_into().log_err())
13088                .collect();
13089        }
13090        self
13091    }
13092    fn with_will_rename_patterns(
13093        mut self,
13094        will_rename: Option<&FileOperationRegistrationOptions>,
13095    ) -> Self {
13096        if let Some(will_rename) = will_rename {
13097            self.will_rename = will_rename
13098                .filters
13099                .iter()
13100                .filter_map(|filter| filter.try_into().log_err())
13101                .collect();
13102        }
13103        self
13104    }
13105
13106    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13107        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13108    }
13109    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13110        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13111    }
13112}
13113
13114impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13115    type Error = globset::Error;
13116    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13117        Ok(Self {
13118            kind: ops.pattern.matches.clone(),
13119            glob: GlobBuilder::new(&ops.pattern.glob)
13120                .case_insensitive(
13121                    ops.pattern
13122                        .options
13123                        .as_ref()
13124                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13125                )
13126                .build()?
13127                .compile_matcher(),
13128        })
13129    }
13130}
13131struct RenameActionPredicate {
13132    glob: GlobMatcher,
13133    kind: Option<FileOperationPatternKind>,
13134}
13135
13136impl RenameActionPredicate {
13137    // Returns true if language server should be notified
13138    fn eval(&self, path: &str, is_dir: bool) -> bool {
13139        self.kind.as_ref().is_none_or(|kind| {
13140            let expected_kind = if is_dir {
13141                FileOperationPatternKind::Folder
13142            } else {
13143                FileOperationPatternKind::File
13144            };
13145            kind == &expected_kind
13146        }) && self.glob.is_match(path)
13147    }
13148}
13149
13150#[derive(Default)]
13151struct LanguageServerWatchedPaths {
13152    worktree_paths: HashMap<WorktreeId, GlobSet>,
13153    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13154}
13155
13156#[derive(Default)]
13157struct LanguageServerWatchedPathsBuilder {
13158    worktree_paths: HashMap<WorktreeId, GlobSet>,
13159    abs_paths: HashMap<Arc<Path>, GlobSet>,
13160}
13161
13162impl LanguageServerWatchedPathsBuilder {
13163    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13164        self.worktree_paths.insert(worktree_id, glob_set);
13165    }
13166    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13167        self.abs_paths.insert(path, glob_set);
13168    }
13169    fn build(
13170        self,
13171        fs: Arc<dyn Fs>,
13172        language_server_id: LanguageServerId,
13173        cx: &mut Context<LspStore>,
13174    ) -> LanguageServerWatchedPaths {
13175        let lsp_store = cx.weak_entity();
13176
13177        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13178        let abs_paths = self
13179            .abs_paths
13180            .into_iter()
13181            .map(|(abs_path, globset)| {
13182                let task = cx.spawn({
13183                    let abs_path = abs_path.clone();
13184                    let fs = fs.clone();
13185
13186                    let lsp_store = lsp_store.clone();
13187                    async move |_, cx| {
13188                        maybe!(async move {
13189                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13190                            while let Some(update) = push_updates.0.next().await {
13191                                let action = lsp_store
13192                                    .update(cx, |this, _| {
13193                                        let Some(local) = this.as_local() else {
13194                                            return ControlFlow::Break(());
13195                                        };
13196                                        let Some(watcher) = local
13197                                            .language_server_watched_paths
13198                                            .get(&language_server_id)
13199                                        else {
13200                                            return ControlFlow::Break(());
13201                                        };
13202                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13203                                            "Watched abs path is not registered with a watcher",
13204                                        );
13205                                        let matching_entries = update
13206                                            .into_iter()
13207                                            .filter(|event| globs.is_match(&event.path))
13208                                            .collect::<Vec<_>>();
13209                                        this.lsp_notify_abs_paths_changed(
13210                                            language_server_id,
13211                                            matching_entries,
13212                                        );
13213                                        ControlFlow::Continue(())
13214                                    })
13215                                    .ok()?;
13216
13217                                if action.is_break() {
13218                                    break;
13219                                }
13220                            }
13221                            Some(())
13222                        })
13223                        .await;
13224                    }
13225                });
13226                (abs_path, (globset, task))
13227            })
13228            .collect();
13229        LanguageServerWatchedPaths {
13230            worktree_paths: self.worktree_paths,
13231            abs_paths,
13232        }
13233    }
13234}
13235
13236struct LspBufferSnapshot {
13237    version: i32,
13238    snapshot: TextBufferSnapshot,
13239}
13240
13241/// A prompt requested by LSP server.
13242#[derive(Clone, Debug)]
13243pub struct LanguageServerPromptRequest {
13244    pub level: PromptLevel,
13245    pub message: String,
13246    pub actions: Vec<MessageActionItem>,
13247    pub lsp_name: String,
13248    pub(crate) response_channel: Sender<MessageActionItem>,
13249}
13250
13251impl LanguageServerPromptRequest {
13252    pub async fn respond(self, index: usize) -> Option<()> {
13253        if let Some(response) = self.actions.into_iter().nth(index) {
13254            self.response_channel.send(response).await.ok()
13255        } else {
13256            None
13257        }
13258    }
13259}
13260impl PartialEq for LanguageServerPromptRequest {
13261    fn eq(&self, other: &Self) -> bool {
13262        self.message == other.message && self.actions == other.actions
13263    }
13264}
13265
13266#[derive(Clone, Debug, PartialEq)]
13267pub enum LanguageServerLogType {
13268    Log(MessageType),
13269    Trace { verbose_info: Option<String> },
13270    Rpc { received: bool },
13271}
13272
13273impl LanguageServerLogType {
13274    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13275        match self {
13276            Self::Log(log_type) => {
13277                use proto::log_message::LogLevel;
13278                let level = match *log_type {
13279                    MessageType::ERROR => LogLevel::Error,
13280                    MessageType::WARNING => LogLevel::Warning,
13281                    MessageType::INFO => LogLevel::Info,
13282                    MessageType::LOG => LogLevel::Log,
13283                    other => {
13284                        log::warn!("Unknown lsp log message type: {other:?}");
13285                        LogLevel::Log
13286                    }
13287                };
13288                proto::language_server_log::LogType::Log(proto::LogMessage {
13289                    level: level as i32,
13290                })
13291            }
13292            Self::Trace { verbose_info } => {
13293                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13294                    verbose_info: verbose_info.to_owned(),
13295                })
13296            }
13297            Self::Rpc { received } => {
13298                let kind = if *received {
13299                    proto::rpc_message::Kind::Received
13300                } else {
13301                    proto::rpc_message::Kind::Sent
13302                };
13303                let kind = kind as i32;
13304                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13305            }
13306        }
13307    }
13308
13309    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13310        use proto::log_message::LogLevel;
13311        use proto::rpc_message;
13312        match log_type {
13313            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13314                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13315                    LogLevel::Error => MessageType::ERROR,
13316                    LogLevel::Warning => MessageType::WARNING,
13317                    LogLevel::Info => MessageType::INFO,
13318                    LogLevel::Log => MessageType::LOG,
13319                },
13320            ),
13321            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13322                verbose_info: trace_message.verbose_info,
13323            },
13324            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13325                received: match rpc_message::Kind::from_i32(message.kind)
13326                    .unwrap_or(rpc_message::Kind::Received)
13327                {
13328                    rpc_message::Kind::Received => true,
13329                    rpc_message::Kind::Sent => false,
13330                },
13331            },
13332        }
13333    }
13334}
13335
13336pub struct WorkspaceRefreshTask {
13337    refresh_tx: mpsc::Sender<()>,
13338    progress_tx: mpsc::Sender<()>,
13339    #[allow(dead_code)]
13340    task: Task<()>,
13341}
13342
13343pub enum LanguageServerState {
13344    Starting {
13345        startup: Task<Option<Arc<LanguageServer>>>,
13346        /// List of language servers that will be added to the workspace once it's initialization completes.
13347        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13348    },
13349
13350    Running {
13351        adapter: Arc<CachedLspAdapter>,
13352        server: Arc<LanguageServer>,
13353        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13354        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13355    },
13356}
13357
13358impl LanguageServerState {
13359    fn add_workspace_folder(&self, uri: Uri) {
13360        match self {
13361            LanguageServerState::Starting {
13362                pending_workspace_folders,
13363                ..
13364            } => {
13365                pending_workspace_folders.lock().insert(uri);
13366            }
13367            LanguageServerState::Running { server, .. } => {
13368                server.add_workspace_folder(uri);
13369            }
13370        }
13371    }
13372    fn _remove_workspace_folder(&self, uri: Uri) {
13373        match self {
13374            LanguageServerState::Starting {
13375                pending_workspace_folders,
13376                ..
13377            } => {
13378                pending_workspace_folders.lock().remove(&uri);
13379            }
13380            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13381        }
13382    }
13383}
13384
13385impl std::fmt::Debug for LanguageServerState {
13386    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13387        match self {
13388            LanguageServerState::Starting { .. } => {
13389                f.debug_struct("LanguageServerState::Starting").finish()
13390            }
13391            LanguageServerState::Running { .. } => {
13392                f.debug_struct("LanguageServerState::Running").finish()
13393            }
13394        }
13395    }
13396}
13397
13398#[derive(Clone, Debug, Serialize)]
13399pub struct LanguageServerProgress {
13400    pub is_disk_based_diagnostics_progress: bool,
13401    pub is_cancellable: bool,
13402    pub title: Option<String>,
13403    pub message: Option<String>,
13404    pub percentage: Option<usize>,
13405    #[serde(skip_serializing)]
13406    pub last_update_at: Instant,
13407}
13408
13409#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13410pub struct DiagnosticSummary {
13411    pub error_count: usize,
13412    pub warning_count: usize,
13413}
13414
13415impl DiagnosticSummary {
13416    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13417        let mut this = Self {
13418            error_count: 0,
13419            warning_count: 0,
13420        };
13421
13422        for entry in diagnostics {
13423            if entry.diagnostic.is_primary {
13424                match entry.diagnostic.severity {
13425                    DiagnosticSeverity::ERROR => this.error_count += 1,
13426                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13427                    _ => {}
13428                }
13429            }
13430        }
13431
13432        this
13433    }
13434
13435    pub fn is_empty(&self) -> bool {
13436        self.error_count == 0 && self.warning_count == 0
13437    }
13438
13439    pub fn to_proto(
13440        self,
13441        language_server_id: LanguageServerId,
13442        path: &RelPath,
13443    ) -> proto::DiagnosticSummary {
13444        proto::DiagnosticSummary {
13445            path: path.to_proto(),
13446            language_server_id: language_server_id.0 as u64,
13447            error_count: self.error_count as u32,
13448            warning_count: self.warning_count as u32,
13449        }
13450    }
13451}
13452
13453#[derive(Clone, Debug)]
13454pub enum CompletionDocumentation {
13455    /// There is no documentation for this completion.
13456    Undocumented,
13457    /// A single line of documentation.
13458    SingleLine(SharedString),
13459    /// Multiple lines of plain text documentation.
13460    MultiLinePlainText(SharedString),
13461    /// Markdown documentation.
13462    MultiLineMarkdown(SharedString),
13463    /// Both single line and multiple lines of plain text documentation.
13464    SingleLineAndMultiLinePlainText {
13465        single_line: SharedString,
13466        plain_text: Option<SharedString>,
13467    },
13468}
13469
13470impl CompletionDocumentation {
13471    #[cfg(any(test, feature = "test-support"))]
13472    pub fn text(&self) -> SharedString {
13473        match self {
13474            CompletionDocumentation::Undocumented => "".into(),
13475            CompletionDocumentation::SingleLine(s) => s.clone(),
13476            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13477            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13478            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13479                single_line.clone()
13480            }
13481        }
13482    }
13483}
13484
13485impl From<lsp::Documentation> for CompletionDocumentation {
13486    fn from(docs: lsp::Documentation) -> Self {
13487        match docs {
13488            lsp::Documentation::String(text) => {
13489                if text.lines().count() <= 1 {
13490                    CompletionDocumentation::SingleLine(text.into())
13491                } else {
13492                    CompletionDocumentation::MultiLinePlainText(text.into())
13493                }
13494            }
13495
13496            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13497                lsp::MarkupKind::PlainText => {
13498                    if value.lines().count() <= 1 {
13499                        CompletionDocumentation::SingleLine(value.into())
13500                    } else {
13501                        CompletionDocumentation::MultiLinePlainText(value.into())
13502                    }
13503                }
13504
13505                lsp::MarkupKind::Markdown => {
13506                    CompletionDocumentation::MultiLineMarkdown(value.into())
13507                }
13508            },
13509        }
13510    }
13511}
13512
13513pub enum ResolvedHint {
13514    Resolved(InlayHint),
13515    Resolving(Shared<Task<()>>),
13516}
13517
13518fn glob_literal_prefix(glob: &Path) -> PathBuf {
13519    glob.components()
13520        .take_while(|component| match component {
13521            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13522            _ => true,
13523        })
13524        .collect()
13525}
13526
13527pub struct SshLspAdapter {
13528    name: LanguageServerName,
13529    binary: LanguageServerBinary,
13530    initialization_options: Option<String>,
13531    code_action_kinds: Option<Vec<CodeActionKind>>,
13532}
13533
13534impl SshLspAdapter {
13535    pub fn new(
13536        name: LanguageServerName,
13537        binary: LanguageServerBinary,
13538        initialization_options: Option<String>,
13539        code_action_kinds: Option<String>,
13540    ) -> Self {
13541        Self {
13542            name,
13543            binary,
13544            initialization_options,
13545            code_action_kinds: code_action_kinds
13546                .as_ref()
13547                .and_then(|c| serde_json::from_str(c).ok()),
13548        }
13549    }
13550}
13551
13552impl LspInstaller for SshLspAdapter {
13553    type BinaryVersion = ();
13554    async fn check_if_user_installed(
13555        &self,
13556        _: &dyn LspAdapterDelegate,
13557        _: Option<Toolchain>,
13558        _: &AsyncApp,
13559    ) -> Option<LanguageServerBinary> {
13560        Some(self.binary.clone())
13561    }
13562
13563    async fn cached_server_binary(
13564        &self,
13565        _: PathBuf,
13566        _: &dyn LspAdapterDelegate,
13567    ) -> Option<LanguageServerBinary> {
13568        None
13569    }
13570
13571    async fn fetch_latest_server_version(
13572        &self,
13573        _: &dyn LspAdapterDelegate,
13574        _: bool,
13575        _: &mut AsyncApp,
13576    ) -> Result<()> {
13577        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13578    }
13579
13580    async fn fetch_server_binary(
13581        &self,
13582        _: (),
13583        _: PathBuf,
13584        _: &dyn LspAdapterDelegate,
13585    ) -> Result<LanguageServerBinary> {
13586        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13587    }
13588}
13589
13590#[async_trait(?Send)]
13591impl LspAdapter for SshLspAdapter {
13592    fn name(&self) -> LanguageServerName {
13593        self.name.clone()
13594    }
13595
13596    async fn initialization_options(
13597        self: Arc<Self>,
13598        _: &Arc<dyn LspAdapterDelegate>,
13599    ) -> Result<Option<serde_json::Value>> {
13600        let Some(options) = &self.initialization_options else {
13601            return Ok(None);
13602        };
13603        let result = serde_json::from_str(options)?;
13604        Ok(result)
13605    }
13606
13607    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13608        self.code_action_kinds.clone()
13609    }
13610}
13611
13612pub fn language_server_settings<'a>(
13613    delegate: &'a dyn LspAdapterDelegate,
13614    language: &LanguageServerName,
13615    cx: &'a App,
13616) -> Option<&'a LspSettings> {
13617    language_server_settings_for(
13618        SettingsLocation {
13619            worktree_id: delegate.worktree_id(),
13620            path: RelPath::empty(),
13621        },
13622        language,
13623        cx,
13624    )
13625}
13626
13627pub(crate) fn language_server_settings_for<'a>(
13628    location: SettingsLocation<'a>,
13629    language: &LanguageServerName,
13630    cx: &'a App,
13631) -> Option<&'a LspSettings> {
13632    ProjectSettings::get(Some(location), cx).lsp.get(language)
13633}
13634
13635pub struct LocalLspAdapterDelegate {
13636    lsp_store: WeakEntity<LspStore>,
13637    worktree: worktree::Snapshot,
13638    fs: Arc<dyn Fs>,
13639    http_client: Arc<dyn HttpClient>,
13640    language_registry: Arc<LanguageRegistry>,
13641    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13642}
13643
13644impl LocalLspAdapterDelegate {
13645    pub fn new(
13646        language_registry: Arc<LanguageRegistry>,
13647        environment: &Entity<ProjectEnvironment>,
13648        lsp_store: WeakEntity<LspStore>,
13649        worktree: &Entity<Worktree>,
13650        http_client: Arc<dyn HttpClient>,
13651        fs: Arc<dyn Fs>,
13652        cx: &mut App,
13653    ) -> Arc<Self> {
13654        let load_shell_env_task =
13655            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13656
13657        Arc::new(Self {
13658            lsp_store,
13659            worktree: worktree.read(cx).snapshot(),
13660            fs,
13661            http_client,
13662            language_registry,
13663            load_shell_env_task,
13664        })
13665    }
13666
13667    fn from_local_lsp(
13668        local: &LocalLspStore,
13669        worktree: &Entity<Worktree>,
13670        cx: &mut App,
13671    ) -> Arc<Self> {
13672        Self::new(
13673            local.languages.clone(),
13674            &local.environment,
13675            local.weak.clone(),
13676            worktree,
13677            local.http_client.clone(),
13678            local.fs.clone(),
13679            cx,
13680        )
13681    }
13682}
13683
13684#[async_trait]
13685impl LspAdapterDelegate for LocalLspAdapterDelegate {
13686    fn show_notification(&self, message: &str, cx: &mut App) {
13687        self.lsp_store
13688            .update(cx, |_, cx| {
13689                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13690            })
13691            .ok();
13692    }
13693
13694    fn http_client(&self) -> Arc<dyn HttpClient> {
13695        self.http_client.clone()
13696    }
13697
13698    fn worktree_id(&self) -> WorktreeId {
13699        self.worktree.id()
13700    }
13701
13702    fn worktree_root_path(&self) -> &Path {
13703        self.worktree.abs_path().as_ref()
13704    }
13705
13706    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13707        self.worktree.resolve_executable_path(path)
13708    }
13709
13710    async fn shell_env(&self) -> HashMap<String, String> {
13711        let task = self.load_shell_env_task.clone();
13712        task.await.unwrap_or_default()
13713    }
13714
13715    async fn npm_package_installed_version(
13716        &self,
13717        package_name: &str,
13718    ) -> Result<Option<(PathBuf, String)>> {
13719        let local_package_directory = self.worktree_root_path();
13720        let node_modules_directory = local_package_directory.join("node_modules");
13721
13722        if let Some(version) =
13723            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13724        {
13725            return Ok(Some((node_modules_directory, version)));
13726        }
13727        let Some(npm) = self.which("npm".as_ref()).await else {
13728            log::warn!(
13729                "Failed to find npm executable for {:?}",
13730                local_package_directory
13731            );
13732            return Ok(None);
13733        };
13734
13735        let env = self.shell_env().await;
13736        let output = util::command::new_smol_command(&npm)
13737            .args(["root", "-g"])
13738            .envs(env)
13739            .current_dir(local_package_directory)
13740            .output()
13741            .await?;
13742        let global_node_modules =
13743            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13744
13745        if let Some(version) =
13746            read_package_installed_version(global_node_modules.clone(), package_name).await?
13747        {
13748            return Ok(Some((global_node_modules, version)));
13749        }
13750        return Ok(None);
13751    }
13752
13753    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13754        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13755        if self.fs.is_file(&worktree_abs_path).await {
13756            worktree_abs_path.pop();
13757        }
13758
13759        let env = self.shell_env().await;
13760
13761        let shell_path = env.get("PATH").cloned();
13762
13763        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13764    }
13765
13766    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13767        let mut working_dir = self.worktree_root_path().to_path_buf();
13768        if self.fs.is_file(&working_dir).await {
13769            working_dir.pop();
13770        }
13771        let output = util::command::new_smol_command(&command.path)
13772            .args(command.arguments)
13773            .envs(command.env.clone().unwrap_or_default())
13774            .current_dir(working_dir)
13775            .output()
13776            .await?;
13777
13778        anyhow::ensure!(
13779            output.status.success(),
13780            "{}, stdout: {:?}, stderr: {:?}",
13781            output.status,
13782            String::from_utf8_lossy(&output.stdout),
13783            String::from_utf8_lossy(&output.stderr)
13784        );
13785        Ok(())
13786    }
13787
13788    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13789        self.language_registry
13790            .update_lsp_binary_status(server_name, status);
13791    }
13792
13793    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13794        self.language_registry
13795            .all_lsp_adapters()
13796            .into_iter()
13797            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13798            .collect()
13799    }
13800
13801    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13802        let dir = self.language_registry.language_server_download_dir(name)?;
13803
13804        if !dir.exists() {
13805            smol::fs::create_dir_all(&dir)
13806                .await
13807                .context("failed to create container directory")
13808                .log_err()?;
13809        }
13810
13811        Some(dir)
13812    }
13813
13814    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13815        let entry = self
13816            .worktree
13817            .entry_for_path(path)
13818            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13819        let abs_path = self.worktree.absolutize(&entry.path);
13820        self.fs.load(&abs_path).await
13821    }
13822}
13823
13824async fn populate_labels_for_symbols(
13825    symbols: Vec<CoreSymbol>,
13826    language_registry: &Arc<LanguageRegistry>,
13827    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13828    output: &mut Vec<Symbol>,
13829) {
13830    #[allow(clippy::mutable_key_type)]
13831    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13832
13833    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13834    for symbol in symbols {
13835        let Some(file_name) = symbol.path.file_name() else {
13836            continue;
13837        };
13838        let language = language_registry
13839            .load_language_for_file_path(Path::new(file_name))
13840            .await
13841            .ok()
13842            .or_else(|| {
13843                unknown_paths.insert(file_name.into());
13844                None
13845            });
13846        symbols_by_language
13847            .entry(language)
13848            .or_default()
13849            .push(symbol);
13850    }
13851
13852    for unknown_path in unknown_paths {
13853        log::info!("no language found for symbol in file {unknown_path:?}");
13854    }
13855
13856    let mut label_params = Vec::new();
13857    for (language, mut symbols) in symbols_by_language {
13858        label_params.clear();
13859        label_params.extend(
13860            symbols
13861                .iter_mut()
13862                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13863        );
13864
13865        let mut labels = Vec::new();
13866        if let Some(language) = language {
13867            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13868                language_registry
13869                    .lsp_adapters(&language.name())
13870                    .first()
13871                    .cloned()
13872            });
13873            if let Some(lsp_adapter) = lsp_adapter {
13874                labels = lsp_adapter
13875                    .labels_for_symbols(&label_params, &language)
13876                    .await
13877                    .log_err()
13878                    .unwrap_or_default();
13879            }
13880        }
13881
13882        for ((symbol, (name, _)), label) in symbols
13883            .into_iter()
13884            .zip(label_params.drain(..))
13885            .zip(labels.into_iter().chain(iter::repeat(None)))
13886        {
13887            output.push(Symbol {
13888                language_server_name: symbol.language_server_name,
13889                source_worktree_id: symbol.source_worktree_id,
13890                source_language_server_id: symbol.source_language_server_id,
13891                path: symbol.path,
13892                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13893                name,
13894                kind: symbol.kind,
13895                range: symbol.range,
13896            });
13897        }
13898    }
13899}
13900
13901fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13902    match server.capabilities().text_document_sync.as_ref()? {
13903        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13904            // Server wants didSave but didn't specify includeText.
13905            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13906            // Server doesn't want didSave at all.
13907            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13908            // Server provided SaveOptions.
13909            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13910                Some(save_options.include_text.unwrap_or(false))
13911            }
13912        },
13913        // We do not have any save info. Kind affects didChange only.
13914        lsp::TextDocumentSyncCapability::Kind(_) => None,
13915    }
13916}
13917
13918/// Completion items are displayed in a `UniformList`.
13919/// Usually, those items are single-line strings, but in LSP responses,
13920/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13921/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13922/// 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,
13923/// breaking the completions menu presentation.
13924///
13925/// 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.
13926fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13927    let mut new_text = String::with_capacity(label.text.len());
13928    let mut offset_map = vec![0; label.text.len() + 1];
13929    let mut last_char_was_space = false;
13930    let mut new_idx = 0;
13931    let chars = label.text.char_indices().fuse();
13932    let mut newlines_removed = false;
13933
13934    for (idx, c) in chars {
13935        offset_map[idx] = new_idx;
13936
13937        match c {
13938            '\n' if last_char_was_space => {
13939                newlines_removed = true;
13940            }
13941            '\t' | ' ' if last_char_was_space => {}
13942            '\n' if !last_char_was_space => {
13943                new_text.push(' ');
13944                new_idx += 1;
13945                last_char_was_space = true;
13946                newlines_removed = true;
13947            }
13948            ' ' | '\t' => {
13949                new_text.push(' ');
13950                new_idx += 1;
13951                last_char_was_space = true;
13952            }
13953            _ => {
13954                new_text.push(c);
13955                new_idx += c.len_utf8();
13956                last_char_was_space = false;
13957            }
13958        }
13959    }
13960    offset_map[label.text.len()] = new_idx;
13961
13962    // Only modify the label if newlines were removed.
13963    if !newlines_removed {
13964        return;
13965    }
13966
13967    let last_index = new_idx;
13968    let mut run_ranges_errors = Vec::new();
13969    label.runs.retain_mut(|(range, _)| {
13970        match offset_map.get(range.start) {
13971            Some(&start) => range.start = start,
13972            None => {
13973                run_ranges_errors.push(range.clone());
13974                return false;
13975            }
13976        }
13977
13978        match offset_map.get(range.end) {
13979            Some(&end) => range.end = end,
13980            None => {
13981                run_ranges_errors.push(range.clone());
13982                range.end = last_index;
13983            }
13984        }
13985        true
13986    });
13987    if !run_ranges_errors.is_empty() {
13988        log::error!(
13989            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13990            label.text
13991        );
13992    }
13993
13994    let mut wrong_filter_range = None;
13995    if label.filter_range == (0..label.text.len()) {
13996        label.filter_range = 0..new_text.len();
13997    } else {
13998        let mut original_filter_range = Some(label.filter_range.clone());
13999        match offset_map.get(label.filter_range.start) {
14000            Some(&start) => label.filter_range.start = start,
14001            None => {
14002                wrong_filter_range = original_filter_range.take();
14003                label.filter_range.start = last_index;
14004            }
14005        }
14006
14007        match offset_map.get(label.filter_range.end) {
14008            Some(&end) => label.filter_range.end = end,
14009            None => {
14010                wrong_filter_range = original_filter_range.take();
14011                label.filter_range.end = last_index;
14012            }
14013        }
14014    }
14015    if let Some(wrong_filter_range) = wrong_filter_range {
14016        log::error!(
14017            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14018            label.text
14019        );
14020    }
14021
14022    label.text = new_text;
14023}
14024
14025#[cfg(test)]
14026mod tests {
14027    use language::HighlightId;
14028
14029    use super::*;
14030
14031    #[test]
14032    fn test_glob_literal_prefix() {
14033        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14034        assert_eq!(
14035            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14036            Path::new("node_modules")
14037        );
14038        assert_eq!(
14039            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14040            Path::new("foo")
14041        );
14042        assert_eq!(
14043            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14044            Path::new("foo/bar/baz.js")
14045        );
14046
14047        #[cfg(target_os = "windows")]
14048        {
14049            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14050            assert_eq!(
14051                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14052                Path::new("node_modules")
14053            );
14054            assert_eq!(
14055                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14056                Path::new("foo")
14057            );
14058            assert_eq!(
14059                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14060                Path::new("foo/bar/baz.js")
14061            );
14062        }
14063    }
14064
14065    #[test]
14066    fn test_multi_len_chars_normalization() {
14067        let mut label = CodeLabel::new(
14068            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14069            0..6,
14070            vec![(0..6, HighlightId(1))],
14071        );
14072        ensure_uniform_list_compatible_label(&mut label);
14073        assert_eq!(
14074            label,
14075            CodeLabel::new(
14076                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14077                0..6,
14078                vec![(0..6, HighlightId(1))],
14079            )
14080        );
14081    }
14082}