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