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