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