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    vec,
  120};
  121use sum_tree::Dimensions;
  122use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  123
  124use util::{
  125    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  126    paths::{PathStyle, SanitizedPath},
  127    post_inc,
  128    rel_path::RelPath,
  129};
  130
  131pub use fs::*;
  132pub use language::Location;
  133pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  134#[cfg(any(test, feature = "test-support"))]
  135pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  136pub use worktree::{
  137    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  138    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  139};
  140
  141const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  142pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  143const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  144const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  145
  146#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  147pub enum ProgressToken {
  148    Number(i32),
  149    String(SharedString),
  150}
  151
  152impl std::fmt::Display for ProgressToken {
  153    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  154        match self {
  155            Self::Number(number) => write!(f, "{number}"),
  156            Self::String(string) => write!(f, "{string}"),
  157        }
  158    }
  159}
  160
  161impl ProgressToken {
  162    fn from_lsp(value: lsp::NumberOrString) -> Self {
  163        match value {
  164            lsp::NumberOrString::Number(number) => Self::Number(number),
  165            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  166        }
  167    }
  168
  169    fn to_lsp(&self) -> lsp::NumberOrString {
  170        match self {
  171            Self::Number(number) => lsp::NumberOrString::Number(*number),
  172            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  173        }
  174    }
  175
  176    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  177        Some(match value.value? {
  178            proto::progress_token::Value::Number(number) => Self::Number(number),
  179            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  180        })
  181    }
  182
  183    fn to_proto(&self) -> proto::ProgressToken {
  184        proto::ProgressToken {
  185            value: Some(match self {
  186                Self::Number(number) => proto::progress_token::Value::Number(*number),
  187                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  188            }),
  189        }
  190    }
  191}
  192
  193#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  194pub enum FormatTrigger {
  195    Save,
  196    Manual,
  197}
  198
  199pub enum LspFormatTarget {
  200    Buffers,
  201    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  202}
  203
  204pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  205
  206impl FormatTrigger {
  207    fn from_proto(value: i32) -> FormatTrigger {
  208        match value {
  209            0 => FormatTrigger::Save,
  210            1 => FormatTrigger::Manual,
  211            _ => FormatTrigger::Save,
  212        }
  213    }
  214}
  215
  216#[derive(Clone)]
  217struct UnifiedLanguageServer {
  218    id: LanguageServerId,
  219    project_roots: HashSet<Arc<RelPath>>,
  220}
  221
  222#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  223struct LanguageServerSeed {
  224    worktree_id: WorktreeId,
  225    name: LanguageServerName,
  226    toolchain: Option<Toolchain>,
  227    settings: Arc<LspSettings>,
  228}
  229
  230#[derive(Debug)]
  231pub struct DocumentDiagnosticsUpdate<'a, D> {
  232    pub diagnostics: D,
  233    pub result_id: Option<SharedString>,
  234    pub registration_id: Option<SharedString>,
  235    pub server_id: LanguageServerId,
  236    pub disk_based_sources: Cow<'a, [String]>,
  237}
  238
  239pub struct DocumentDiagnostics {
  240    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  241    document_abs_path: PathBuf,
  242    version: Option<i32>,
  243}
  244
  245#[derive(Default, Debug)]
  246struct DynamicRegistrations {
  247    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  248    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  249}
  250
  251pub struct LocalLspStore {
  252    weak: WeakEntity<LspStore>,
  253    worktree_store: Entity<WorktreeStore>,
  254    toolchain_store: Entity<LocalToolchainStore>,
  255    http_client: Arc<dyn HttpClient>,
  256    environment: Entity<ProjectEnvironment>,
  257    fs: Arc<dyn Fs>,
  258    languages: Arc<LanguageRegistry>,
  259    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  260    yarn: Entity<YarnPathStore>,
  261    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  262    buffers_being_formatted: HashSet<BufferId>,
  263    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  264    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  265    watched_manifest_filenames: HashSet<ManifestName>,
  266    language_server_paths_watched_for_rename:
  267        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  268    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  269    supplementary_language_servers:
  270        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  271    prettier_store: Entity<PrettierStore>,
  272    next_diagnostic_group_id: usize,
  273    diagnostics: HashMap<
  274        WorktreeId,
  275        HashMap<
  276            Arc<RelPath>,
  277            Vec<(
  278                LanguageServerId,
  279                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  280            )>,
  281        >,
  282    >,
  283    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  284    _subscription: gpui::Subscription,
  285    lsp_tree: LanguageServerTree,
  286    registered_buffers: HashMap<BufferId, usize>,
  287    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  288    buffer_pull_diagnostics_result_ids: HashMap<
  289        LanguageServerId,
  290        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  291    >,
  292    workspace_pull_diagnostics_result_ids: HashMap<
  293        LanguageServerId,
  294        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  295    >,
  296}
  297
  298impl LocalLspStore {
  299    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  300    pub fn running_language_server_for_id(
  301        &self,
  302        id: LanguageServerId,
  303    ) -> Option<&Arc<LanguageServer>> {
  304        let language_server_state = self.language_servers.get(&id)?;
  305
  306        match language_server_state {
  307            LanguageServerState::Running { server, .. } => Some(server),
  308            LanguageServerState::Starting { .. } => None,
  309        }
  310    }
  311
  312    fn get_or_insert_language_server(
  313        &mut self,
  314        worktree_handle: &Entity<Worktree>,
  315        delegate: Arc<LocalLspAdapterDelegate>,
  316        disposition: &Arc<LaunchDisposition>,
  317        language_name: &LanguageName,
  318        cx: &mut App,
  319    ) -> LanguageServerId {
  320        let key = LanguageServerSeed {
  321            worktree_id: worktree_handle.read(cx).id(),
  322            name: disposition.server_name.clone(),
  323            settings: disposition.settings.clone(),
  324            toolchain: disposition.toolchain.clone(),
  325        };
  326        if let Some(state) = self.language_server_ids.get_mut(&key) {
  327            state.project_roots.insert(disposition.path.path.clone());
  328            state.id
  329        } else {
  330            let adapter = self
  331                .languages
  332                .lsp_adapters(language_name)
  333                .into_iter()
  334                .find(|adapter| adapter.name() == disposition.server_name)
  335                .expect("To find LSP adapter");
  336            let new_language_server_id = self.start_language_server(
  337                worktree_handle,
  338                delegate,
  339                adapter,
  340                disposition.settings.clone(),
  341                key.clone(),
  342                cx,
  343            );
  344            if let Some(state) = self.language_server_ids.get_mut(&key) {
  345                state.project_roots.insert(disposition.path.path.clone());
  346            } else {
  347                debug_assert!(
  348                    false,
  349                    "Expected `start_language_server` to ensure that `key` exists in a map"
  350                );
  351            }
  352            new_language_server_id
  353        }
  354    }
  355
  356    fn start_language_server(
  357        &mut self,
  358        worktree_handle: &Entity<Worktree>,
  359        delegate: Arc<LocalLspAdapterDelegate>,
  360        adapter: Arc<CachedLspAdapter>,
  361        settings: Arc<LspSettings>,
  362        key: LanguageServerSeed,
  363        cx: &mut App,
  364    ) -> LanguageServerId {
  365        let worktree = worktree_handle.read(cx);
  366
  367        let root_path = worktree.abs_path();
  368        let toolchain = key.toolchain.clone();
  369        let override_options = settings.initialization_options.clone();
  370
  371        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  372
  373        let server_id = self.languages.next_language_server_id();
  374        log::trace!(
  375            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  376            adapter.name.0
  377        );
  378
  379        let binary = self.get_language_server_binary(
  380            adapter.clone(),
  381            settings,
  382            toolchain.clone(),
  383            delegate.clone(),
  384            true,
  385            cx,
  386        );
  387        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  388
  389        let pending_server = cx.spawn({
  390            let adapter = adapter.clone();
  391            let server_name = adapter.name.clone();
  392            let stderr_capture = stderr_capture.clone();
  393            #[cfg(any(test, feature = "test-support"))]
  394            let lsp_store = self.weak.clone();
  395            let pending_workspace_folders = pending_workspace_folders.clone();
  396            async move |cx| {
  397                let binary = binary.await?;
  398                #[cfg(any(test, feature = "test-support"))]
  399                if let Some(server) = lsp_store
  400                    .update(&mut cx.clone(), |this, cx| {
  401                        this.languages.create_fake_language_server(
  402                            server_id,
  403                            &server_name,
  404                            binary.clone(),
  405                            &mut cx.to_async(),
  406                        )
  407                    })
  408                    .ok()
  409                    .flatten()
  410                {
  411                    return Ok(server);
  412                }
  413
  414                let code_action_kinds = adapter.code_action_kinds();
  415                lsp::LanguageServer::new(
  416                    stderr_capture,
  417                    server_id,
  418                    server_name,
  419                    binary,
  420                    &root_path,
  421                    code_action_kinds,
  422                    Some(pending_workspace_folders),
  423                    cx,
  424                )
  425                .await
  426            }
  427        });
  428
  429        let startup = {
  430            let server_name = adapter.name.0.clone();
  431            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  432            let key = key.clone();
  433            let adapter = adapter.clone();
  434            let lsp_store = self.weak.clone();
  435            let pending_workspace_folders = pending_workspace_folders.clone();
  436
  437            let pull_diagnostics = ProjectSettings::get_global(cx)
  438                .diagnostics
  439                .lsp_pull_diagnostics
  440                .enabled;
  441            cx.spawn(async move |cx| {
  442                let result = async {
  443                    let language_server = pending_server.await?;
  444
  445                    let workspace_config = Self::workspace_configuration_for_adapter(
  446                        adapter.adapter.clone(),
  447                        &delegate,
  448                        toolchain,
  449                        None,
  450                        cx,
  451                    )
  452                    .await?;
  453
  454                    let mut initialization_options = Self::initialization_options_for_adapter(
  455                        adapter.adapter.clone(),
  456                        &delegate,
  457                    )
  458                    .await?;
  459
  460                    match (&mut initialization_options, override_options) {
  461                        (Some(initialization_options), Some(override_options)) => {
  462                            merge_json_value_into(override_options, initialization_options);
  463                        }
  464                        (None, override_options) => initialization_options = override_options,
  465                        _ => {}
  466                    }
  467
  468                    let initialization_params = cx.update(|cx| {
  469                        let mut params =
  470                            language_server.default_initialize_params(pull_diagnostics, cx);
  471                        params.initialization_options = initialization_options;
  472                        adapter.adapter.prepare_initialize_params(params, cx)
  473                    })??;
  474
  475                    Self::setup_lsp_messages(
  476                        lsp_store.clone(),
  477                        &language_server,
  478                        delegate.clone(),
  479                        adapter.clone(),
  480                    );
  481
  482                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  483                        settings: workspace_config,
  484                    };
  485                    let language_server = cx
  486                        .update(|cx| {
  487                            language_server.initialize(
  488                                initialization_params,
  489                                Arc::new(did_change_configuration_params.clone()),
  490                                cx,
  491                            )
  492                        })?
  493                        .await
  494                        .inspect_err(|_| {
  495                            if let Some(lsp_store) = lsp_store.upgrade() {
  496                                lsp_store
  497                                    .update(cx, |lsp_store, cx| {
  498                                        lsp_store.cleanup_lsp_data(server_id);
  499                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  500                                    })
  501                                    .ok();
  502                            }
  503                        })?;
  504
  505                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  506                        did_change_configuration_params,
  507                    )?;
  508
  509                    anyhow::Ok(language_server)
  510                }
  511                .await;
  512
  513                match result {
  514                    Ok(server) => {
  515                        lsp_store
  516                            .update(cx, |lsp_store, cx| {
  517                                lsp_store.insert_newly_running_language_server(
  518                                    adapter,
  519                                    server.clone(),
  520                                    server_id,
  521                                    key,
  522                                    pending_workspace_folders,
  523                                    cx,
  524                                );
  525                            })
  526                            .ok();
  527                        stderr_capture.lock().take();
  528                        Some(server)
  529                    }
  530
  531                    Err(err) => {
  532                        let log = stderr_capture.lock().take().unwrap_or_default();
  533                        delegate.update_status(
  534                            adapter.name(),
  535                            BinaryStatus::Failed {
  536                                error: if log.is_empty() {
  537                                    format!("{err:#}")
  538                                } else {
  539                                    format!("{err:#}\n-- stderr --\n{log}")
  540                                },
  541                            },
  542                        );
  543                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  544                        if !log.is_empty() {
  545                            log::error!("server stderr: {log}");
  546                        }
  547                        None
  548                    }
  549                }
  550            })
  551        };
  552        let state = LanguageServerState::Starting {
  553            startup,
  554            pending_workspace_folders,
  555        };
  556
  557        self.languages
  558            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  559
  560        self.language_servers.insert(server_id, state);
  561        self.language_server_ids
  562            .entry(key)
  563            .or_insert(UnifiedLanguageServer {
  564                id: server_id,
  565                project_roots: Default::default(),
  566            });
  567        server_id
  568    }
  569
  570    fn get_language_server_binary(
  571        &self,
  572        adapter: Arc<CachedLspAdapter>,
  573        settings: Arc<LspSettings>,
  574        toolchain: Option<Toolchain>,
  575        delegate: Arc<dyn LspAdapterDelegate>,
  576        allow_binary_download: bool,
  577        cx: &mut App,
  578    ) -> Task<Result<LanguageServerBinary>> {
  579        if let Some(settings) = &settings.binary
  580            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  581        {
  582            let settings = settings.clone();
  583
  584            return cx.background_spawn(async move {
  585                let mut env = delegate.shell_env().await;
  586                env.extend(settings.env.unwrap_or_default());
  587
  588                Ok(LanguageServerBinary {
  589                    path: delegate.resolve_executable_path(path),
  590                    env: Some(env),
  591                    arguments: settings
  592                        .arguments
  593                        .unwrap_or_default()
  594                        .iter()
  595                        .map(Into::into)
  596                        .collect(),
  597                })
  598            });
  599        }
  600        let lsp_binary_options = LanguageServerBinaryOptions {
  601            allow_path_lookup: !settings
  602                .binary
  603                .as_ref()
  604                .and_then(|b| b.ignore_system_version)
  605                .unwrap_or_default(),
  606            allow_binary_download,
  607            pre_release: settings
  608                .fetch
  609                .as_ref()
  610                .and_then(|f| f.pre_release)
  611                .unwrap_or(false),
  612        };
  613
  614        cx.spawn(async move |cx| {
  615            let (existing_binary, maybe_download_binary) = adapter
  616                .clone()
  617                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  618                .await
  619                .await;
  620
  621            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  622
  623            let mut binary = match (existing_binary, maybe_download_binary) {
  624                (binary, None) => binary?,
  625                (Err(_), Some(downloader)) => downloader.await?,
  626                (Ok(existing_binary), Some(downloader)) => {
  627                    let mut download_timeout = cx
  628                        .background_executor()
  629                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  630                        .fuse();
  631                    let mut downloader = downloader.fuse();
  632                    futures::select! {
  633                        _ = download_timeout => {
  634                            // Return existing binary and kick the existing work to the background.
  635                            cx.spawn(async move |_| downloader.await).detach();
  636                            Ok(existing_binary)
  637                        },
  638                        downloaded_or_existing_binary = downloader => {
  639                            // If download fails, this results in the existing binary.
  640                            downloaded_or_existing_binary
  641                        }
  642                    }?
  643                }
  644            };
  645            let mut shell_env = delegate.shell_env().await;
  646
  647            shell_env.extend(binary.env.unwrap_or_default());
  648
  649            if let Some(settings) = settings.binary.as_ref() {
  650                if let Some(arguments) = &settings.arguments {
  651                    binary.arguments = arguments.iter().map(Into::into).collect();
  652                }
  653                if let Some(env) = &settings.env {
  654                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  655                }
  656            }
  657
  658            binary.env = Some(shell_env);
  659            Ok(binary)
  660        })
  661    }
  662
  663    fn setup_lsp_messages(
  664        lsp_store: WeakEntity<LspStore>,
  665        language_server: &LanguageServer,
  666        delegate: Arc<dyn LspAdapterDelegate>,
  667        adapter: Arc<CachedLspAdapter>,
  668    ) {
  669        let name = language_server.name();
  670        let server_id = language_server.server_id();
  671        language_server
  672            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  673                let adapter = adapter.clone();
  674                let this = lsp_store.clone();
  675                move |mut params, cx| {
  676                    let adapter = adapter.clone();
  677                    if let Some(this) = this.upgrade() {
  678                        this.update(cx, |this, cx| {
  679                            {
  680                                let buffer = params
  681                                    .uri
  682                                    .to_file_path()
  683                                    .map(|file_path| this.get_buffer(&file_path, cx))
  684                                    .ok()
  685                                    .flatten();
  686                                adapter.process_diagnostics(&mut params, server_id, buffer);
  687                            }
  688
  689                            this.merge_lsp_diagnostics(
  690                                DiagnosticSourceKind::Pushed,
  691                                vec![DocumentDiagnosticsUpdate {
  692                                    server_id,
  693                                    diagnostics: params,
  694                                    result_id: None,
  695                                    disk_based_sources: Cow::Borrowed(
  696                                        &adapter.disk_based_diagnostic_sources,
  697                                    ),
  698                                    registration_id: None,
  699                                }],
  700                                |_, diagnostic, cx| match diagnostic.source_kind {
  701                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  702                                        adapter.retain_old_diagnostic(diagnostic, cx)
  703                                    }
  704                                    DiagnosticSourceKind::Pulled => true,
  705                                },
  706                                cx,
  707                            )
  708                            .log_err();
  709                        })
  710                        .ok();
  711                    }
  712                }
  713            })
  714            .detach();
  715        language_server
  716            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  717                let adapter = adapter.adapter.clone();
  718                let delegate = delegate.clone();
  719                let this = lsp_store.clone();
  720                move |params, cx| {
  721                    let adapter = adapter.clone();
  722                    let delegate = delegate.clone();
  723                    let this = this.clone();
  724                    let mut cx = cx.clone();
  725                    async move {
  726                        let toolchain_for_id = this
  727                            .update(&mut cx, |this, _| {
  728                                this.as_local()?.language_server_ids.iter().find_map(
  729                                    |(seed, value)| {
  730                                        (value.id == server_id).then(|| seed.toolchain.clone())
  731                                    },
  732                                )
  733                            })?
  734                            .context("Expected the LSP store to be in a local mode")?;
  735
  736                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  737                        for item in &params.items {
  738                            let scope_uri = item.scope_uri.clone();
  739                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  740                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  741                            else {
  742                                // We've already queried workspace configuration of this URI.
  743                                continue;
  744                            };
  745                            let workspace_config = Self::workspace_configuration_for_adapter(
  746                                adapter.clone(),
  747                                &delegate,
  748                                toolchain_for_id.clone(),
  749                                scope_uri,
  750                                &mut cx,
  751                            )
  752                            .await?;
  753                            new_scope_uri.insert(workspace_config);
  754                        }
  755
  756                        Ok(params
  757                            .items
  758                            .into_iter()
  759                            .filter_map(|item| {
  760                                let workspace_config =
  761                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  762                                if let Some(section) = &item.section {
  763                                    Some(
  764                                        workspace_config
  765                                            .get(section)
  766                                            .cloned()
  767                                            .unwrap_or(serde_json::Value::Null),
  768                                    )
  769                                } else {
  770                                    Some(workspace_config.clone())
  771                                }
  772                            })
  773                            .collect())
  774                    }
  775                }
  776            })
  777            .detach();
  778
  779        language_server
  780            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  781                let this = lsp_store.clone();
  782                move |_, cx| {
  783                    let this = this.clone();
  784                    let cx = cx.clone();
  785                    async move {
  786                        let Some(server) =
  787                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  788                        else {
  789                            return Ok(None);
  790                        };
  791                        let root = server.workspace_folders();
  792                        Ok(Some(
  793                            root.into_iter()
  794                                .map(|uri| WorkspaceFolder {
  795                                    uri,
  796                                    name: Default::default(),
  797                                })
  798                                .collect(),
  799                        ))
  800                    }
  801                }
  802            })
  803            .detach();
  804        // Even though we don't have handling for these requests, respond to them to
  805        // avoid stalling any language server like `gopls` which waits for a response
  806        // to these requests when initializing.
  807        language_server
  808            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  809                let this = lsp_store.clone();
  810                move |params, cx| {
  811                    let this = this.clone();
  812                    let mut cx = cx.clone();
  813                    async move {
  814                        this.update(&mut cx, |this, _| {
  815                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  816                            {
  817                                status
  818                                    .progress_tokens
  819                                    .insert(ProgressToken::from_lsp(params.token));
  820                            }
  821                        })?;
  822
  823                        Ok(())
  824                    }
  825                }
  826            })
  827            .detach();
  828
  829        language_server
  830            .on_request::<lsp::request::RegisterCapability, _, _>({
  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                                        .register_server_capabilities(server_id, params, cx)
  841                                    {
  842                                        Ok(()) => {}
  843                                        Err(e) => {
  844                                            log::error!(
  845                                                "Failed to register 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::UnregisterCapability, _, _>({
  860                let lsp_store = lsp_store.clone();
  861                move |params, cx| {
  862                    let lsp_store = lsp_store.clone();
  863                    let mut cx = cx.clone();
  864                    async move {
  865                        lsp_store
  866                            .update(&mut cx, |lsp_store, cx| {
  867                                if lsp_store.as_local().is_some() {
  868                                    match lsp_store
  869                                        .unregister_server_capabilities(server_id, params, cx)
  870                                    {
  871                                        Ok(()) => {}
  872                                        Err(e) => {
  873                                            log::error!(
  874                                                "Failed to unregister server capabilities: {e:#}"
  875                                            );
  876                                        }
  877                                    }
  878                                }
  879                            })
  880                            .ok();
  881                        Ok(())
  882                    }
  883                }
  884            })
  885            .detach();
  886
  887        language_server
  888            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  889                let this = lsp_store.clone();
  890                move |params, cx| {
  891                    let mut cx = cx.clone();
  892                    let this = this.clone();
  893                    async move {
  894                        LocalLspStore::on_lsp_workspace_edit(
  895                            this.clone(),
  896                            params,
  897                            server_id,
  898                            &mut cx,
  899                        )
  900                        .await
  901                    }
  902                }
  903            })
  904            .detach();
  905
  906        language_server
  907            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  908                let lsp_store = lsp_store.clone();
  909                let request_id = Arc::new(AtomicUsize::new(0));
  910                move |(), cx| {
  911                    let lsp_store = lsp_store.clone();
  912                    let request_id = request_id.clone();
  913                    let mut cx = cx.clone();
  914                    async move {
  915                        lsp_store
  916                            .update(&mut cx, |lsp_store, cx| {
  917                                let request_id =
  918                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  919                                cx.emit(LspStoreEvent::RefreshInlayHints {
  920                                    server_id,
  921                                    request_id,
  922                                });
  923                                lsp_store
  924                                    .downstream_client
  925                                    .as_ref()
  926                                    .map(|(client, project_id)| {
  927                                        client.send(proto::RefreshInlayHints {
  928                                            project_id: *project_id,
  929                                            server_id: server_id.to_proto(),
  930                                            request_id: request_id.map(|id| id as u64),
  931                                        })
  932                                    })
  933                            })?
  934                            .transpose()?;
  935                        Ok(())
  936                    }
  937                }
  938            })
  939            .detach();
  940
  941        language_server
  942            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  943                let this = lsp_store.clone();
  944                move |(), cx| {
  945                    let this = this.clone();
  946                    let mut cx = cx.clone();
  947                    async move {
  948                        this.update(&mut cx, |this, cx| {
  949                            cx.emit(LspStoreEvent::RefreshCodeLens);
  950                            this.downstream_client.as_ref().map(|(client, project_id)| {
  951                                client.send(proto::RefreshCodeLens {
  952                                    project_id: *project_id,
  953                                })
  954                            })
  955                        })?
  956                        .transpose()?;
  957                        Ok(())
  958                    }
  959                }
  960            })
  961            .detach();
  962
  963        language_server
  964            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  965                let this = lsp_store.clone();
  966                move |(), cx| {
  967                    let this = this.clone();
  968                    let mut cx = cx.clone();
  969                    async move {
  970                        this.update(&mut cx, |lsp_store, _| {
  971                            lsp_store.pull_workspace_diagnostics(server_id);
  972                            lsp_store
  973                                .downstream_client
  974                                .as_ref()
  975                                .map(|(client, project_id)| {
  976                                    client.send(proto::PullWorkspaceDiagnostics {
  977                                        project_id: *project_id,
  978                                        server_id: server_id.to_proto(),
  979                                    })
  980                                })
  981                        })?
  982                        .transpose()?;
  983                        Ok(())
  984                    }
  985                }
  986            })
  987            .detach();
  988
  989        language_server
  990            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  991                let this = lsp_store.clone();
  992                let name = name.to_string();
  993                move |params, cx| {
  994                    let this = this.clone();
  995                    let name = name.to_string();
  996                    let mut cx = cx.clone();
  997                    async move {
  998                        let actions = params.actions.unwrap_or_default();
  999                        let (tx, rx) = smol::channel::bounded(1);
 1000                        let request = LanguageServerPromptRequest {
 1001                            level: match params.typ {
 1002                                lsp::MessageType::ERROR => PromptLevel::Critical,
 1003                                lsp::MessageType::WARNING => PromptLevel::Warning,
 1004                                _ => PromptLevel::Info,
 1005                            },
 1006                            message: params.message,
 1007                            actions,
 1008                            response_channel: tx,
 1009                            lsp_name: name.clone(),
 1010                        };
 1011
 1012                        let did_update = this
 1013                            .update(&mut cx, |_, cx| {
 1014                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1015                            })
 1016                            .is_ok();
 1017                        if did_update {
 1018                            let response = rx.recv().await.ok();
 1019                            Ok(response)
 1020                        } else {
 1021                            Ok(None)
 1022                        }
 1023                    }
 1024                }
 1025            })
 1026            .detach();
 1027        language_server
 1028            .on_notification::<lsp::notification::ShowMessage, _>({
 1029                let this = lsp_store.clone();
 1030                let name = name.to_string();
 1031                move |params, cx| {
 1032                    let this = this.clone();
 1033                    let name = name.to_string();
 1034                    let mut cx = cx.clone();
 1035
 1036                    let (tx, _) = smol::channel::bounded(1);
 1037                    let request = LanguageServerPromptRequest {
 1038                        level: match params.typ {
 1039                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1040                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1041                            _ => PromptLevel::Info,
 1042                        },
 1043                        message: params.message,
 1044                        actions: vec![],
 1045                        response_channel: tx,
 1046                        lsp_name: name,
 1047                    };
 1048
 1049                    let _ = this.update(&mut cx, |_, cx| {
 1050                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1051                    });
 1052                }
 1053            })
 1054            .detach();
 1055
 1056        let disk_based_diagnostics_progress_token =
 1057            adapter.disk_based_diagnostics_progress_token.clone();
 1058
 1059        language_server
 1060            .on_notification::<lsp::notification::Progress, _>({
 1061                let this = lsp_store.clone();
 1062                move |params, cx| {
 1063                    if let Some(this) = this.upgrade() {
 1064                        this.update(cx, |this, cx| {
 1065                            this.on_lsp_progress(
 1066                                params,
 1067                                server_id,
 1068                                disk_based_diagnostics_progress_token.clone(),
 1069                                cx,
 1070                            );
 1071                        })
 1072                        .ok();
 1073                    }
 1074                }
 1075            })
 1076            .detach();
 1077
 1078        language_server
 1079            .on_notification::<lsp::notification::LogMessage, _>({
 1080                let this = lsp_store.clone();
 1081                move |params, cx| {
 1082                    if let Some(this) = this.upgrade() {
 1083                        this.update(cx, |_, cx| {
 1084                            cx.emit(LspStoreEvent::LanguageServerLog(
 1085                                server_id,
 1086                                LanguageServerLogType::Log(params.typ),
 1087                                params.message,
 1088                            ));
 1089                        })
 1090                        .ok();
 1091                    }
 1092                }
 1093            })
 1094            .detach();
 1095
 1096        language_server
 1097            .on_notification::<lsp::notification::LogTrace, _>({
 1098                let this = lsp_store.clone();
 1099                move |params, cx| {
 1100                    let mut cx = cx.clone();
 1101                    if let Some(this) = this.upgrade() {
 1102                        this.update(&mut cx, |_, cx| {
 1103                            cx.emit(LspStoreEvent::LanguageServerLog(
 1104                                server_id,
 1105                                LanguageServerLogType::Trace {
 1106                                    verbose_info: params.verbose,
 1107                                },
 1108                                params.message,
 1109                            ));
 1110                        })
 1111                        .ok();
 1112                    }
 1113                }
 1114            })
 1115            .detach();
 1116
 1117        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1118        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1119        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1120        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1121    }
 1122
 1123    fn shutdown_language_servers_on_quit(
 1124        &mut self,
 1125        _: &mut Context<LspStore>,
 1126    ) -> impl Future<Output = ()> + use<> {
 1127        let shutdown_futures = self
 1128            .language_servers
 1129            .drain()
 1130            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1131            .collect::<Vec<_>>();
 1132
 1133        async move {
 1134            join_all(shutdown_futures).await;
 1135        }
 1136    }
 1137
 1138    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1139        match server_state {
 1140            LanguageServerState::Running { server, .. } => {
 1141                if let Some(shutdown) = server.shutdown() {
 1142                    shutdown.await;
 1143                }
 1144            }
 1145            LanguageServerState::Starting { startup, .. } => {
 1146                if let Some(server) = startup.await
 1147                    && let Some(shutdown) = server.shutdown()
 1148                {
 1149                    shutdown.await;
 1150                }
 1151            }
 1152        }
 1153        Ok(())
 1154    }
 1155
 1156    fn language_servers_for_worktree(
 1157        &self,
 1158        worktree_id: WorktreeId,
 1159    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1160        self.language_server_ids
 1161            .iter()
 1162            .filter_map(move |(seed, state)| {
 1163                if seed.worktree_id != worktree_id {
 1164                    return None;
 1165                }
 1166
 1167                if let Some(LanguageServerState::Running { server, .. }) =
 1168                    self.language_servers.get(&state.id)
 1169                {
 1170                    Some(server)
 1171                } else {
 1172                    None
 1173                }
 1174            })
 1175    }
 1176
 1177    fn language_server_ids_for_project_path(
 1178        &self,
 1179        project_path: ProjectPath,
 1180        language: &Language,
 1181        cx: &mut App,
 1182    ) -> Vec<LanguageServerId> {
 1183        let Some(worktree) = self
 1184            .worktree_store
 1185            .read(cx)
 1186            .worktree_for_id(project_path.worktree_id, cx)
 1187        else {
 1188            return Vec::new();
 1189        };
 1190        let delegate: Arc<dyn ManifestDelegate> =
 1191            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1192
 1193        self.lsp_tree
 1194            .get(
 1195                project_path,
 1196                language.name(),
 1197                language.manifest(),
 1198                &delegate,
 1199                cx,
 1200            )
 1201            .collect::<Vec<_>>()
 1202    }
 1203
 1204    fn language_server_ids_for_buffer(
 1205        &self,
 1206        buffer: &Buffer,
 1207        cx: &mut App,
 1208    ) -> Vec<LanguageServerId> {
 1209        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1210            let worktree_id = file.worktree_id(cx);
 1211
 1212            let path: Arc<RelPath> = file
 1213                .path()
 1214                .parent()
 1215                .map(Arc::from)
 1216                .unwrap_or_else(|| file.path().clone());
 1217            let worktree_path = ProjectPath { worktree_id, path };
 1218            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1219        } else {
 1220            Vec::new()
 1221        }
 1222    }
 1223
 1224    fn language_servers_for_buffer<'a>(
 1225        &'a self,
 1226        buffer: &'a Buffer,
 1227        cx: &'a mut App,
 1228    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1229        self.language_server_ids_for_buffer(buffer, cx)
 1230            .into_iter()
 1231            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1232                LanguageServerState::Running {
 1233                    adapter, server, ..
 1234                } => Some((adapter, server)),
 1235                _ => None,
 1236            })
 1237    }
 1238
 1239    async fn execute_code_action_kind_locally(
 1240        lsp_store: WeakEntity<LspStore>,
 1241        mut buffers: Vec<Entity<Buffer>>,
 1242        kind: CodeActionKind,
 1243        push_to_history: bool,
 1244        cx: &mut AsyncApp,
 1245    ) -> anyhow::Result<ProjectTransaction> {
 1246        // Do not allow multiple concurrent code actions requests for the
 1247        // same buffer.
 1248        lsp_store.update(cx, |this, cx| {
 1249            let this = this.as_local_mut().unwrap();
 1250            buffers.retain(|buffer| {
 1251                this.buffers_being_formatted
 1252                    .insert(buffer.read(cx).remote_id())
 1253            });
 1254        })?;
 1255        let _cleanup = defer({
 1256            let this = lsp_store.clone();
 1257            let mut cx = cx.clone();
 1258            let buffers = &buffers;
 1259            move || {
 1260                this.update(&mut cx, |this, cx| {
 1261                    let this = this.as_local_mut().unwrap();
 1262                    for buffer in buffers {
 1263                        this.buffers_being_formatted
 1264                            .remove(&buffer.read(cx).remote_id());
 1265                    }
 1266                })
 1267                .ok();
 1268            }
 1269        });
 1270        let mut project_transaction = ProjectTransaction::default();
 1271
 1272        for buffer in &buffers {
 1273            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1274                buffer.update(cx, |buffer, cx| {
 1275                    lsp_store
 1276                        .as_local()
 1277                        .unwrap()
 1278                        .language_servers_for_buffer(buffer, cx)
 1279                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1280                        .collect::<Vec<_>>()
 1281                })
 1282            })?;
 1283            for (_, language_server) in adapters_and_servers.iter() {
 1284                let actions = Self::get_server_code_actions_from_action_kinds(
 1285                    &lsp_store,
 1286                    language_server.server_id(),
 1287                    vec![kind.clone()],
 1288                    buffer,
 1289                    cx,
 1290                )
 1291                .await?;
 1292                Self::execute_code_actions_on_server(
 1293                    &lsp_store,
 1294                    language_server,
 1295                    actions,
 1296                    push_to_history,
 1297                    &mut project_transaction,
 1298                    cx,
 1299                )
 1300                .await?;
 1301            }
 1302        }
 1303        Ok(project_transaction)
 1304    }
 1305
 1306    async fn format_locally(
 1307        lsp_store: WeakEntity<LspStore>,
 1308        mut buffers: Vec<FormattableBuffer>,
 1309        push_to_history: bool,
 1310        trigger: FormatTrigger,
 1311        logger: zlog::Logger,
 1312        cx: &mut AsyncApp,
 1313    ) -> anyhow::Result<ProjectTransaction> {
 1314        // Do not allow multiple concurrent formatting requests for the
 1315        // same buffer.
 1316        lsp_store.update(cx, |this, cx| {
 1317            let this = this.as_local_mut().unwrap();
 1318            buffers.retain(|buffer| {
 1319                this.buffers_being_formatted
 1320                    .insert(buffer.handle.read(cx).remote_id())
 1321            });
 1322        })?;
 1323
 1324        let _cleanup = defer({
 1325            let this = lsp_store.clone();
 1326            let mut cx = cx.clone();
 1327            let buffers = &buffers;
 1328            move || {
 1329                this.update(&mut cx, |this, cx| {
 1330                    let this = this.as_local_mut().unwrap();
 1331                    for buffer in buffers {
 1332                        this.buffers_being_formatted
 1333                            .remove(&buffer.handle.read(cx).remote_id());
 1334                    }
 1335                })
 1336                .ok();
 1337            }
 1338        });
 1339
 1340        let mut project_transaction = ProjectTransaction::default();
 1341
 1342        for buffer in &buffers {
 1343            zlog::debug!(
 1344                logger =>
 1345                "formatting buffer '{:?}'",
 1346                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1347            );
 1348            // Create an empty transaction to hold all of the formatting edits.
 1349            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1350                // ensure no transactions created while formatting are
 1351                // grouped with the previous transaction in the history
 1352                // based on the transaction group interval
 1353                buffer.finalize_last_transaction();
 1354                buffer
 1355                    .start_transaction()
 1356                    .context("transaction already open")?;
 1357                buffer.end_transaction(cx);
 1358                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1359                buffer.finalize_last_transaction();
 1360                anyhow::Ok(transaction_id)
 1361            })??;
 1362
 1363            let result = Self::format_buffer_locally(
 1364                lsp_store.clone(),
 1365                buffer,
 1366                formatting_transaction_id,
 1367                trigger,
 1368                logger,
 1369                cx,
 1370            )
 1371            .await;
 1372
 1373            buffer.handle.update(cx, |buffer, cx| {
 1374                let Some(formatting_transaction) =
 1375                    buffer.get_transaction(formatting_transaction_id).cloned()
 1376                else {
 1377                    zlog::warn!(logger => "no formatting transaction");
 1378                    return;
 1379                };
 1380                if formatting_transaction.edit_ids.is_empty() {
 1381                    zlog::debug!(logger => "no changes made while formatting");
 1382                    buffer.forget_transaction(formatting_transaction_id);
 1383                    return;
 1384                }
 1385                if !push_to_history {
 1386                    zlog::trace!(logger => "forgetting format transaction");
 1387                    buffer.forget_transaction(formatting_transaction.id);
 1388                }
 1389                project_transaction
 1390                    .0
 1391                    .insert(cx.entity(), formatting_transaction);
 1392            })?;
 1393
 1394            result?;
 1395        }
 1396
 1397        Ok(project_transaction)
 1398    }
 1399
 1400    async fn format_buffer_locally(
 1401        lsp_store: WeakEntity<LspStore>,
 1402        buffer: &FormattableBuffer,
 1403        formatting_transaction_id: clock::Lamport,
 1404        trigger: FormatTrigger,
 1405        logger: zlog::Logger,
 1406        cx: &mut AsyncApp,
 1407    ) -> Result<()> {
 1408        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1409            buffer.handle.update(cx, |buffer, cx| {
 1410                let adapters_and_servers = lsp_store
 1411                    .as_local()
 1412                    .unwrap()
 1413                    .language_servers_for_buffer(buffer, cx)
 1414                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1415                    .collect::<Vec<_>>();
 1416                let settings =
 1417                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1418                        .into_owned();
 1419                (adapters_and_servers, settings)
 1420            })
 1421        })?;
 1422
 1423        /// Apply edits to the buffer that will become part of the formatting transaction.
 1424        /// Fails if the buffer has been edited since the start of that transaction.
 1425        fn extend_formatting_transaction(
 1426            buffer: &FormattableBuffer,
 1427            formatting_transaction_id: text::TransactionId,
 1428            cx: &mut AsyncApp,
 1429            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1430        ) -> anyhow::Result<()> {
 1431            buffer.handle.update(cx, |buffer, cx| {
 1432                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1433                if last_transaction_id != Some(formatting_transaction_id) {
 1434                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1435                }
 1436                buffer.start_transaction();
 1437                operation(buffer, cx);
 1438                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1439                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1440                }
 1441                Ok(())
 1442            })?
 1443        }
 1444
 1445        // handle whitespace formatting
 1446        if settings.remove_trailing_whitespace_on_save {
 1447            zlog::trace!(logger => "removing trailing whitespace");
 1448            let diff = buffer
 1449                .handle
 1450                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1451                .await;
 1452            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1453                buffer.apply_diff(diff, cx);
 1454            })?;
 1455        }
 1456
 1457        if settings.ensure_final_newline_on_save {
 1458            zlog::trace!(logger => "ensuring final newline");
 1459            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1460                buffer.ensure_final_newline(cx);
 1461            })?;
 1462        }
 1463
 1464        // Formatter for `code_actions_on_format` that runs before
 1465        // the rest of the formatters
 1466        let mut code_actions_on_format_formatters = None;
 1467        let should_run_code_actions_on_format = !matches!(
 1468            (trigger, &settings.format_on_save),
 1469            (FormatTrigger::Save, &FormatOnSave::Off)
 1470        );
 1471        if should_run_code_actions_on_format {
 1472            let have_code_actions_to_run_on_format = settings
 1473                .code_actions_on_format
 1474                .values()
 1475                .any(|enabled| *enabled);
 1476            if have_code_actions_to_run_on_format {
 1477                zlog::trace!(logger => "going to run code actions on format");
 1478                code_actions_on_format_formatters = Some(
 1479                    settings
 1480                        .code_actions_on_format
 1481                        .iter()
 1482                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1483                        .cloned()
 1484                        .map(Formatter::CodeAction)
 1485                        .collect::<Vec<_>>(),
 1486                );
 1487            }
 1488        }
 1489
 1490        let formatters = match (trigger, &settings.format_on_save) {
 1491            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1492            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1493                settings.formatter.as_ref()
 1494            }
 1495        };
 1496
 1497        let formatters = code_actions_on_format_formatters
 1498            .iter()
 1499            .flatten()
 1500            .chain(formatters);
 1501
 1502        for formatter in formatters {
 1503            let formatter = if formatter == &Formatter::Auto {
 1504                if settings.prettier.allowed {
 1505                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1506                    &Formatter::Prettier
 1507                } else {
 1508                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1509                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1510                }
 1511            } else {
 1512                formatter
 1513            };
 1514            match formatter {
 1515                Formatter::Auto => unreachable!("Auto resolved above"),
 1516                Formatter::Prettier => {
 1517                    let logger = zlog::scoped!(logger => "prettier");
 1518                    zlog::trace!(logger => "formatting");
 1519                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1520
 1521                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1522                        lsp_store.prettier_store().unwrap().downgrade()
 1523                    })?;
 1524                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1525                        .await
 1526                        .transpose()?;
 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::External { command, arguments } => {
 1542                    let logger = zlog::scoped!(logger => "command");
 1543                    zlog::trace!(logger => "formatting");
 1544                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1545
 1546                    let diff = Self::format_via_external_command(
 1547                        buffer,
 1548                        command.as_ref(),
 1549                        arguments.as_deref(),
 1550                        cx,
 1551                    )
 1552                    .await
 1553                    .with_context(|| {
 1554                        format!("Failed to format buffer via external command: {}", command)
 1555                    })?;
 1556                    let Some(diff) = diff else {
 1557                        zlog::trace!(logger => "No changes");
 1558                        continue;
 1559                    };
 1560
 1561                    extend_formatting_transaction(
 1562                        buffer,
 1563                        formatting_transaction_id,
 1564                        cx,
 1565                        |buffer, cx| {
 1566                            buffer.apply_diff(diff, cx);
 1567                        },
 1568                    )?;
 1569                }
 1570                Formatter::LanguageServer(specifier) => {
 1571                    let logger = zlog::scoped!(logger => "language-server");
 1572                    zlog::trace!(logger => "formatting");
 1573                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1574
 1575                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1576                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1577                        continue;
 1578                    };
 1579
 1580                    let language_server = match specifier {
 1581                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1582                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1583                                if adapter.name.0.as_ref() == name {
 1584                                    Some(server.clone())
 1585                                } else {
 1586                                    None
 1587                                }
 1588                            })
 1589                        }
 1590                        settings::LanguageServerFormatterSpecifier::Current => {
 1591                            adapters_and_servers.first().map(|e| e.1.clone())
 1592                        }
 1593                    };
 1594
 1595                    let Some(language_server) = language_server else {
 1596                        log::debug!(
 1597                            "No language server found to format buffer '{:?}'. Skipping",
 1598                            buffer_path_abs.as_path().to_string_lossy()
 1599                        );
 1600                        continue;
 1601                    };
 1602
 1603                    zlog::trace!(
 1604                        logger =>
 1605                        "Formatting buffer '{:?}' using language server '{:?}'",
 1606                        buffer_path_abs.as_path().to_string_lossy(),
 1607                        language_server.name()
 1608                    );
 1609
 1610                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1611                        zlog::trace!(logger => "formatting ranges");
 1612                        Self::format_ranges_via_lsp(
 1613                            &lsp_store,
 1614                            &buffer.handle,
 1615                            ranges,
 1616                            buffer_path_abs,
 1617                            &language_server,
 1618                            &settings,
 1619                            cx,
 1620                        )
 1621                        .await
 1622                        .context("Failed to format ranges via language server")?
 1623                    } else {
 1624                        zlog::trace!(logger => "formatting full");
 1625                        Self::format_via_lsp(
 1626                            &lsp_store,
 1627                            &buffer.handle,
 1628                            buffer_path_abs,
 1629                            &language_server,
 1630                            &settings,
 1631                            cx,
 1632                        )
 1633                        .await
 1634                        .context("failed to format via language server")?
 1635                    };
 1636
 1637                    if edits.is_empty() {
 1638                        zlog::trace!(logger => "No changes");
 1639                        continue;
 1640                    }
 1641                    extend_formatting_transaction(
 1642                        buffer,
 1643                        formatting_transaction_id,
 1644                        cx,
 1645                        |buffer, cx| {
 1646                            buffer.edit(edits, None, cx);
 1647                        },
 1648                    )?;
 1649                }
 1650                Formatter::CodeAction(code_action_name) => {
 1651                    let logger = zlog::scoped!(logger => "code-actions");
 1652                    zlog::trace!(logger => "formatting");
 1653                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1654
 1655                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1656                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1657                        continue;
 1658                    };
 1659
 1660                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1661                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1662
 1663                    let mut actions_and_servers = Vec::new();
 1664
 1665                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1666                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1667                            &lsp_store,
 1668                            language_server.server_id(),
 1669                            vec![code_action_kind.clone()],
 1670                            &buffer.handle,
 1671                            cx,
 1672                        )
 1673                        .await
 1674                        .with_context(|| {
 1675                            format!(
 1676                                "Failed to resolve code action {:?} with language server {}",
 1677                                code_action_kind,
 1678                                language_server.name()
 1679                            )
 1680                        });
 1681                        let Ok(actions) = actions_result else {
 1682                            // note: it may be better to set result to the error and break formatters here
 1683                            // but for now we try to execute the actions that we can resolve and skip the rest
 1684                            zlog::error!(
 1685                                logger =>
 1686                                "Failed to resolve code action {:?} with language server {}",
 1687                                code_action_kind,
 1688                                language_server.name()
 1689                            );
 1690                            continue;
 1691                        };
 1692                        for action in actions {
 1693                            actions_and_servers.push((action, index));
 1694                        }
 1695                    }
 1696
 1697                    if actions_and_servers.is_empty() {
 1698                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1699                        continue;
 1700                    }
 1701
 1702                    'actions: for (mut action, server_index) in actions_and_servers {
 1703                        let server = &adapters_and_servers[server_index].1;
 1704
 1705                        let describe_code_action = |action: &CodeAction| {
 1706                            format!(
 1707                                "code action '{}' with title \"{}\" on server {}",
 1708                                action
 1709                                    .lsp_action
 1710                                    .action_kind()
 1711                                    .unwrap_or("unknown".into())
 1712                                    .as_str(),
 1713                                action.lsp_action.title(),
 1714                                server.name(),
 1715                            )
 1716                        };
 1717
 1718                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1719
 1720                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1721                            zlog::error!(
 1722                                logger =>
 1723                                "Failed to resolve {}. Error: {}",
 1724                                describe_code_action(&action),
 1725                                err
 1726                            );
 1727                            continue;
 1728                        }
 1729
 1730                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1731                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1732                            // but filters out and logs warnings for code actions that require unreasonably
 1733                            // difficult handling on our part, such as:
 1734                            // - applying edits that call commands
 1735                            //   which can result in arbitrary workspace edits being sent from the server that
 1736                            //   have no way of being tied back to the command that initiated them (i.e. we
 1737                            //   can't know which edits are part of the format request, or if the server is done sending
 1738                            //   actions in response to the command)
 1739                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1740                            //   as we then would need to handle such changes correctly in the local history as well
 1741                            //   as the remote history through the ProjectTransaction
 1742                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1743                            // Supporting these actions is not impossible, but not supported as of yet.
 1744                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1745                                zlog::trace!(
 1746                                    logger =>
 1747                                    "No changes for code action. Skipping {}",
 1748                                    describe_code_action(&action),
 1749                                );
 1750                                continue;
 1751                            }
 1752
 1753                            let mut operations = Vec::new();
 1754                            if let Some(document_changes) = edit.document_changes {
 1755                                match document_changes {
 1756                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1757                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1758                                    ),
 1759                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1760                                }
 1761                            } else if let Some(changes) = edit.changes {
 1762                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1763                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1764                                        text_document:
 1765                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1766                                                uri,
 1767                                                version: None,
 1768                                            },
 1769                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1770                                    })
 1771                                }));
 1772                            }
 1773
 1774                            let mut edits = Vec::with_capacity(operations.len());
 1775
 1776                            if operations.is_empty() {
 1777                                zlog::trace!(
 1778                                    logger =>
 1779                                    "No changes for code action. Skipping {}",
 1780                                    describe_code_action(&action),
 1781                                );
 1782                                continue;
 1783                            }
 1784                            for operation in operations {
 1785                                let op = match operation {
 1786                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1787                                    lsp::DocumentChangeOperation::Op(_) => {
 1788                                        zlog::warn!(
 1789                                            logger =>
 1790                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1791                                            describe_code_action(&action),
 1792                                        );
 1793                                        continue 'actions;
 1794                                    }
 1795                                };
 1796                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1797                                    zlog::warn!(
 1798                                        logger =>
 1799                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1800                                        &op.text_document.uri,
 1801                                        describe_code_action(&action),
 1802                                    );
 1803                                    continue 'actions;
 1804                                };
 1805                                if &file_path != buffer_path_abs {
 1806                                    zlog::warn!(
 1807                                        logger =>
 1808                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1809                                        file_path,
 1810                                        buffer_path_abs,
 1811                                        describe_code_action(&action),
 1812                                    );
 1813                                    continue 'actions;
 1814                                }
 1815
 1816                                let mut lsp_edits = Vec::new();
 1817                                for edit in op.edits {
 1818                                    match edit {
 1819                                        Edit::Plain(edit) => {
 1820                                            if !lsp_edits.contains(&edit) {
 1821                                                lsp_edits.push(edit);
 1822                                            }
 1823                                        }
 1824                                        Edit::Annotated(edit) => {
 1825                                            if !lsp_edits.contains(&edit.text_edit) {
 1826                                                lsp_edits.push(edit.text_edit);
 1827                                            }
 1828                                        }
 1829                                        Edit::Snippet(_) => {
 1830                                            zlog::warn!(
 1831                                                logger =>
 1832                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1833                                                describe_code_action(&action),
 1834                                            );
 1835                                            continue 'actions;
 1836                                        }
 1837                                    }
 1838                                }
 1839                                let edits_result = lsp_store
 1840                                    .update(cx, |lsp_store, cx| {
 1841                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1842                                            &buffer.handle,
 1843                                            lsp_edits,
 1844                                            server.server_id(),
 1845                                            op.text_document.version,
 1846                                            cx,
 1847                                        )
 1848                                    })?
 1849                                    .await;
 1850                                let Ok(resolved_edits) = edits_result else {
 1851                                    zlog::warn!(
 1852                                        logger =>
 1853                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1854                                        buffer_path_abs.as_path(),
 1855                                        describe_code_action(&action),
 1856                                    );
 1857                                    continue 'actions;
 1858                                };
 1859                                edits.extend(resolved_edits);
 1860                            }
 1861
 1862                            if edits.is_empty() {
 1863                                zlog::warn!(logger => "No edits resolved from LSP");
 1864                                continue;
 1865                            }
 1866
 1867                            extend_formatting_transaction(
 1868                                buffer,
 1869                                formatting_transaction_id,
 1870                                cx,
 1871                                |buffer, cx| {
 1872                                    zlog::info!(
 1873                                        "Applying edits {edits:?}. Content: {:?}",
 1874                                        buffer.text()
 1875                                    );
 1876                                    buffer.edit(edits, None, cx);
 1877                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1878                                },
 1879                            )?;
 1880                        }
 1881
 1882                        if let Some(command) = action.lsp_action.command() {
 1883                            zlog::warn!(
 1884                                logger =>
 1885                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1886                                &command.command,
 1887                            );
 1888
 1889                            // bail early if command is invalid
 1890                            let server_capabilities = server.capabilities();
 1891                            let available_commands = server_capabilities
 1892                                .execute_command_provider
 1893                                .as_ref()
 1894                                .map(|options| options.commands.as_slice())
 1895                                .unwrap_or_default();
 1896                            if !available_commands.contains(&command.command) {
 1897                                zlog::warn!(
 1898                                    logger =>
 1899                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1900                                    command.command,
 1901                                    server.name(),
 1902                                );
 1903                                continue;
 1904                            }
 1905
 1906                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1907                            extend_formatting_transaction(
 1908                                buffer,
 1909                                formatting_transaction_id,
 1910                                cx,
 1911                                |_, _| {},
 1912                            )?;
 1913                            zlog::info!(logger => "Executing command {}", &command.command);
 1914
 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                            })?;
 1921
 1922                            let execute_command_result = server
 1923                                .request::<lsp::request::ExecuteCommand>(
 1924                                    lsp::ExecuteCommandParams {
 1925                                        command: command.command.clone(),
 1926                                        arguments: command.arguments.clone().unwrap_or_default(),
 1927                                        ..Default::default()
 1928                                    },
 1929                                )
 1930                                .await
 1931                                .into_response();
 1932
 1933                            if execute_command_result.is_err() {
 1934                                zlog::error!(
 1935                                    logger =>
 1936                                    "Failed to execute command '{}' as part of {}",
 1937                                    &command.command,
 1938                                    describe_code_action(&action),
 1939                                );
 1940                                continue 'actions;
 1941                            }
 1942
 1943                            let mut project_transaction_command =
 1944                                lsp_store.update(cx, |this, _| {
 1945                                    this.as_local_mut()
 1946                                        .unwrap()
 1947                                        .last_workspace_edits_by_language_server
 1948                                        .remove(&server.server_id())
 1949                                        .unwrap_or_default()
 1950                                })?;
 1951
 1952                            if let Some(transaction) =
 1953                                project_transaction_command.0.remove(&buffer.handle)
 1954                            {
 1955                                zlog::trace!(
 1956                                    logger =>
 1957                                    "Successfully captured {} edits that resulted from command {}",
 1958                                    transaction.edit_ids.len(),
 1959                                    &command.command,
 1960                                );
 1961                                let transaction_id_project_transaction = transaction.id;
 1962                                buffer.handle.update(cx, |buffer, _| {
 1963                                    // it may have been removed from history if push_to_history was
 1964                                    // false in deserialize_workspace_edit. If so push it so we
 1965                                    // can merge it with the format transaction
 1966                                    // and pop the combined transaction off the history stack
 1967                                    // later if push_to_history is false
 1968                                    if buffer.get_transaction(transaction.id).is_none() {
 1969                                        buffer.push_transaction(transaction, Instant::now());
 1970                                    }
 1971                                    buffer.merge_transactions(
 1972                                        transaction_id_project_transaction,
 1973                                        formatting_transaction_id,
 1974                                    );
 1975                                })?;
 1976                            }
 1977
 1978                            if !project_transaction_command.0.is_empty() {
 1979                                let mut extra_buffers = String::new();
 1980                                for buffer in project_transaction_command.0.keys() {
 1981                                    buffer
 1982                                        .read_with(cx, |b, cx| {
 1983                                            if let Some(path) = b.project_path(cx) {
 1984                                                if !extra_buffers.is_empty() {
 1985                                                    extra_buffers.push_str(", ");
 1986                                                }
 1987                                                extra_buffers.push_str(path.path.as_unix_str());
 1988                                            }
 1989                                        })
 1990                                        .ok();
 1991                                }
 1992                                zlog::warn!(
 1993                                    logger =>
 1994                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1995                                    &command.command,
 1996                                    extra_buffers,
 1997                                );
 1998                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1999                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2000                                // add it so it's included, and merge it into the format transaction when its created later
 2001                            }
 2002                        }
 2003                    }
 2004                }
 2005            }
 2006        }
 2007
 2008        Ok(())
 2009    }
 2010
 2011    pub async fn format_ranges_via_lsp(
 2012        this: &WeakEntity<LspStore>,
 2013        buffer_handle: &Entity<Buffer>,
 2014        ranges: &[Range<Anchor>],
 2015        abs_path: &Path,
 2016        language_server: &Arc<LanguageServer>,
 2017        settings: &LanguageSettings,
 2018        cx: &mut AsyncApp,
 2019    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2020        let capabilities = &language_server.capabilities();
 2021        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2022        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2023            anyhow::bail!(
 2024                "{} language server does not support range formatting",
 2025                language_server.name()
 2026            );
 2027        }
 2028
 2029        let uri = file_path_to_lsp_url(abs_path)?;
 2030        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2031
 2032        let lsp_edits = {
 2033            let mut lsp_ranges = Vec::new();
 2034            this.update(cx, |_this, cx| {
 2035                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2036                // not have been sent to the language server. This seems like a fairly systemic
 2037                // issue, though, the resolution probably is not specific to formatting.
 2038                //
 2039                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2040                // LSP.
 2041                let snapshot = buffer_handle.read(cx).snapshot();
 2042                for range in ranges {
 2043                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2044                }
 2045                anyhow::Ok(())
 2046            })??;
 2047
 2048            let mut edits = None;
 2049            for range in lsp_ranges {
 2050                if let Some(mut edit) = language_server
 2051                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2052                        text_document: text_document.clone(),
 2053                        range,
 2054                        options: lsp_command::lsp_formatting_options(settings),
 2055                        work_done_progress_params: Default::default(),
 2056                    })
 2057                    .await
 2058                    .into_response()?
 2059                {
 2060                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2061                }
 2062            }
 2063            edits
 2064        };
 2065
 2066        if let Some(lsp_edits) = lsp_edits {
 2067            this.update(cx, |this, cx| {
 2068                this.as_local_mut().unwrap().edits_from_lsp(
 2069                    buffer_handle,
 2070                    lsp_edits,
 2071                    language_server.server_id(),
 2072                    None,
 2073                    cx,
 2074                )
 2075            })?
 2076            .await
 2077        } else {
 2078            Ok(Vec::with_capacity(0))
 2079        }
 2080    }
 2081
 2082    async fn format_via_lsp(
 2083        this: &WeakEntity<LspStore>,
 2084        buffer: &Entity<Buffer>,
 2085        abs_path: &Path,
 2086        language_server: &Arc<LanguageServer>,
 2087        settings: &LanguageSettings,
 2088        cx: &mut AsyncApp,
 2089    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2090        let logger = zlog::scoped!("lsp_format");
 2091        zlog::debug!(logger => "Formatting via LSP");
 2092
 2093        let uri = file_path_to_lsp_url(abs_path)?;
 2094        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2095        let capabilities = &language_server.capabilities();
 2096
 2097        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2098        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2099
 2100        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2101            let _timer = zlog::time!(logger => "format-full");
 2102            language_server
 2103                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2104                    text_document,
 2105                    options: lsp_command::lsp_formatting_options(settings),
 2106                    work_done_progress_params: Default::default(),
 2107                })
 2108                .await
 2109                .into_response()?
 2110        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2111            let _timer = zlog::time!(logger => "format-range");
 2112            let buffer_start = lsp::Position::new(0, 0);
 2113            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2114            language_server
 2115                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2116                    text_document: text_document.clone(),
 2117                    range: lsp::Range::new(buffer_start, buffer_end),
 2118                    options: lsp_command::lsp_formatting_options(settings),
 2119                    work_done_progress_params: Default::default(),
 2120                })
 2121                .await
 2122                .into_response()?
 2123        } else {
 2124            None
 2125        };
 2126
 2127        if let Some(lsp_edits) = lsp_edits {
 2128            this.update(cx, |this, cx| {
 2129                this.as_local_mut().unwrap().edits_from_lsp(
 2130                    buffer,
 2131                    lsp_edits,
 2132                    language_server.server_id(),
 2133                    None,
 2134                    cx,
 2135                )
 2136            })?
 2137            .await
 2138        } else {
 2139            Ok(Vec::with_capacity(0))
 2140        }
 2141    }
 2142
 2143    async fn format_via_external_command(
 2144        buffer: &FormattableBuffer,
 2145        command: &str,
 2146        arguments: Option<&[String]>,
 2147        cx: &mut AsyncApp,
 2148    ) -> Result<Option<Diff>> {
 2149        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2150            let file = File::from_dyn(buffer.file())?;
 2151            let worktree = file.worktree.read(cx);
 2152            let mut worktree_path = worktree.abs_path().to_path_buf();
 2153            if worktree.root_entry()?.is_file() {
 2154                worktree_path.pop();
 2155            }
 2156            Some(worktree_path)
 2157        })?;
 2158
 2159        let mut child = util::command::new_smol_command(command);
 2160
 2161        if let Some(buffer_env) = buffer.env.as_ref() {
 2162            child.envs(buffer_env);
 2163        }
 2164
 2165        if let Some(working_dir_path) = working_dir_path {
 2166            child.current_dir(working_dir_path);
 2167        }
 2168
 2169        if let Some(arguments) = arguments {
 2170            child.args(arguments.iter().map(|arg| {
 2171                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2172                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2173                } else {
 2174                    arg.replace("{buffer_path}", "Untitled")
 2175                }
 2176            }));
 2177        }
 2178
 2179        let mut child = child
 2180            .stdin(smol::process::Stdio::piped())
 2181            .stdout(smol::process::Stdio::piped())
 2182            .stderr(smol::process::Stdio::piped())
 2183            .spawn()?;
 2184
 2185        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2186        let text = buffer
 2187            .handle
 2188            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2189        for chunk in text.chunks() {
 2190            stdin.write_all(chunk.as_bytes()).await?;
 2191        }
 2192        stdin.flush().await?;
 2193
 2194        let output = child.output().await?;
 2195        anyhow::ensure!(
 2196            output.status.success(),
 2197            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2198            output.status.code(),
 2199            String::from_utf8_lossy(&output.stdout),
 2200            String::from_utf8_lossy(&output.stderr),
 2201        );
 2202
 2203        let stdout = String::from_utf8(output.stdout)?;
 2204        Ok(Some(
 2205            buffer
 2206                .handle
 2207                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2208                .await,
 2209        ))
 2210    }
 2211
 2212    async fn try_resolve_code_action(
 2213        lang_server: &LanguageServer,
 2214        action: &mut CodeAction,
 2215    ) -> anyhow::Result<()> {
 2216        match &mut action.lsp_action {
 2217            LspAction::Action(lsp_action) => {
 2218                if !action.resolved
 2219                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2220                    && lsp_action.data.is_some()
 2221                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2222                {
 2223                    *lsp_action = Box::new(
 2224                        lang_server
 2225                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2226                            .await
 2227                            .into_response()?,
 2228                    );
 2229                }
 2230            }
 2231            LspAction::CodeLens(lens) => {
 2232                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2233                    *lens = lang_server
 2234                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2235                        .await
 2236                        .into_response()?;
 2237                }
 2238            }
 2239            LspAction::Command(_) => {}
 2240        }
 2241
 2242        action.resolved = true;
 2243        anyhow::Ok(())
 2244    }
 2245
 2246    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2247        let buffer = buffer_handle.read(cx);
 2248
 2249        let file = buffer.file().cloned();
 2250
 2251        let Some(file) = File::from_dyn(file.as_ref()) else {
 2252            return;
 2253        };
 2254        if !file.is_local() {
 2255            return;
 2256        }
 2257        let path = ProjectPath::from_file(file, cx);
 2258        let worktree_id = file.worktree_id(cx);
 2259        let language = buffer.language().cloned();
 2260
 2261        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2262            for (server_id, diagnostics) in
 2263                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2264            {
 2265                self.update_buffer_diagnostics(
 2266                    buffer_handle,
 2267                    server_id,
 2268                    None,
 2269                    None,
 2270                    None,
 2271                    Vec::new(),
 2272                    diagnostics,
 2273                    cx,
 2274                )
 2275                .log_err();
 2276            }
 2277        }
 2278        let Some(language) = language else {
 2279            return;
 2280        };
 2281        let Some(snapshot) = self
 2282            .worktree_store
 2283            .read(cx)
 2284            .worktree_for_id(worktree_id, cx)
 2285            .map(|worktree| worktree.read(cx).snapshot())
 2286        else {
 2287            return;
 2288        };
 2289        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2290
 2291        for server_id in
 2292            self.lsp_tree
 2293                .get(path, language.name(), language.manifest(), &delegate, cx)
 2294        {
 2295            let server = self
 2296                .language_servers
 2297                .get(&server_id)
 2298                .and_then(|server_state| {
 2299                    if let LanguageServerState::Running { server, .. } = server_state {
 2300                        Some(server.clone())
 2301                    } else {
 2302                        None
 2303                    }
 2304                });
 2305            let server = match server {
 2306                Some(server) => server,
 2307                None => continue,
 2308            };
 2309
 2310            buffer_handle.update(cx, |buffer, cx| {
 2311                buffer.set_completion_triggers(
 2312                    server.server_id(),
 2313                    server
 2314                        .capabilities()
 2315                        .completion_provider
 2316                        .as_ref()
 2317                        .and_then(|provider| {
 2318                            provider
 2319                                .trigger_characters
 2320                                .as_ref()
 2321                                .map(|characters| characters.iter().cloned().collect())
 2322                        })
 2323                        .unwrap_or_default(),
 2324                    cx,
 2325                );
 2326            });
 2327        }
 2328    }
 2329
 2330    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2331        buffer.update(cx, |buffer, cx| {
 2332            let Some(language) = buffer.language() else {
 2333                return;
 2334            };
 2335            let path = ProjectPath {
 2336                worktree_id: old_file.worktree_id(cx),
 2337                path: old_file.path.clone(),
 2338            };
 2339            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2340                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2341                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2342            }
 2343        });
 2344    }
 2345
 2346    fn update_buffer_diagnostics(
 2347        &mut self,
 2348        buffer: &Entity<Buffer>,
 2349        server_id: LanguageServerId,
 2350        registration_id: Option<Option<SharedString>>,
 2351        result_id: Option<SharedString>,
 2352        version: Option<i32>,
 2353        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2354        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2355        cx: &mut Context<LspStore>,
 2356    ) -> Result<()> {
 2357        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2358            Ordering::Equal
 2359                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2360                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2361                .then_with(|| a.severity.cmp(&b.severity))
 2362                .then_with(|| a.message.cmp(&b.message))
 2363        }
 2364
 2365        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2366        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2367        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2368
 2369        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2370            Ordering::Equal
 2371                .then_with(|| a.range.start.cmp(&b.range.start))
 2372                .then_with(|| b.range.end.cmp(&a.range.end))
 2373                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2374        });
 2375
 2376        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2377
 2378        let edits_since_save = std::cell::LazyCell::new(|| {
 2379            let saved_version = buffer.read(cx).saved_version();
 2380            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2381        });
 2382
 2383        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2384
 2385        for (new_diagnostic, entry) in diagnostics {
 2386            let start;
 2387            let end;
 2388            if new_diagnostic && entry.diagnostic.is_disk_based {
 2389                // Some diagnostics are based on files on disk instead of buffers'
 2390                // current contents. Adjust these diagnostics' ranges to reflect
 2391                // any unsaved edits.
 2392                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2393                // and were properly adjusted on reuse.
 2394                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2395                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2396            } else {
 2397                start = entry.range.start;
 2398                end = entry.range.end;
 2399            }
 2400
 2401            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2402                ..snapshot.clip_point_utf16(end, Bias::Right);
 2403
 2404            // Expand empty ranges by one codepoint
 2405            if range.start == range.end {
 2406                // This will be go to the next boundary when being clipped
 2407                range.end.column += 1;
 2408                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2409                if range.start == range.end && range.end.column > 0 {
 2410                    range.start.column -= 1;
 2411                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2412                }
 2413            }
 2414
 2415            sanitized_diagnostics.push(DiagnosticEntry {
 2416                range,
 2417                diagnostic: entry.diagnostic,
 2418            });
 2419        }
 2420        drop(edits_since_save);
 2421
 2422        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2423        buffer.update(cx, |buffer, cx| {
 2424            if let Some(registration_id) = registration_id {
 2425                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2426                    self.buffer_pull_diagnostics_result_ids
 2427                        .entry(server_id)
 2428                        .or_default()
 2429                        .entry(registration_id)
 2430                        .or_default()
 2431                        .insert(abs_path, result_id);
 2432                }
 2433            }
 2434
 2435            buffer.update_diagnostics(server_id, set, cx)
 2436        });
 2437
 2438        Ok(())
 2439    }
 2440
 2441    fn register_language_server_for_invisible_worktree(
 2442        &mut self,
 2443        worktree: &Entity<Worktree>,
 2444        language_server_id: LanguageServerId,
 2445        cx: &mut App,
 2446    ) {
 2447        let worktree = worktree.read(cx);
 2448        let worktree_id = worktree.id();
 2449        debug_assert!(!worktree.is_visible());
 2450        let Some(mut origin_seed) = self
 2451            .language_server_ids
 2452            .iter()
 2453            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2454        else {
 2455            return;
 2456        };
 2457        origin_seed.worktree_id = worktree_id;
 2458        self.language_server_ids
 2459            .entry(origin_seed)
 2460            .or_insert_with(|| UnifiedLanguageServer {
 2461                id: language_server_id,
 2462                project_roots: Default::default(),
 2463            });
 2464    }
 2465
 2466    fn register_buffer_with_language_servers(
 2467        &mut self,
 2468        buffer_handle: &Entity<Buffer>,
 2469        only_register_servers: HashSet<LanguageServerSelector>,
 2470        cx: &mut Context<LspStore>,
 2471    ) {
 2472        let buffer = buffer_handle.read(cx);
 2473        let buffer_id = buffer.remote_id();
 2474
 2475        let Some(file) = File::from_dyn(buffer.file()) else {
 2476            return;
 2477        };
 2478        if !file.is_local() {
 2479            return;
 2480        }
 2481
 2482        let abs_path = file.abs_path(cx);
 2483        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2484            return;
 2485        };
 2486        let initial_snapshot = buffer.text_snapshot();
 2487        let worktree_id = file.worktree_id(cx);
 2488
 2489        let Some(language) = buffer.language().cloned() else {
 2490            return;
 2491        };
 2492        let path: Arc<RelPath> = file
 2493            .path()
 2494            .parent()
 2495            .map(Arc::from)
 2496            .unwrap_or_else(|| file.path().clone());
 2497        let Some(worktree) = self
 2498            .worktree_store
 2499            .read(cx)
 2500            .worktree_for_id(worktree_id, cx)
 2501        else {
 2502            return;
 2503        };
 2504        let language_name = language.name();
 2505        let (reused, delegate, servers) = self
 2506            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2507            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2508            .unwrap_or_else(|| {
 2509                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2510                let delegate: Arc<dyn ManifestDelegate> =
 2511                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2512
 2513                let servers = self
 2514                    .lsp_tree
 2515                    .walk(
 2516                        ProjectPath { worktree_id, path },
 2517                        language.name(),
 2518                        language.manifest(),
 2519                        &delegate,
 2520                        cx,
 2521                    )
 2522                    .collect::<Vec<_>>();
 2523                (false, lsp_delegate, servers)
 2524            });
 2525        let servers_and_adapters = servers
 2526            .into_iter()
 2527            .filter_map(|server_node| {
 2528                if reused && server_node.server_id().is_none() {
 2529                    return None;
 2530                }
 2531                if !only_register_servers.is_empty() {
 2532                    if let Some(server_id) = server_node.server_id()
 2533                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2534                    {
 2535                        return None;
 2536                    }
 2537                    if let Some(name) = server_node.name()
 2538                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2539                    {
 2540                        return None;
 2541                    }
 2542                }
 2543
 2544                let server_id = server_node.server_id_or_init(|disposition| {
 2545                    let path = &disposition.path;
 2546
 2547                    {
 2548                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2549
 2550                        let server_id = self.get_or_insert_language_server(
 2551                            &worktree,
 2552                            delegate.clone(),
 2553                            disposition,
 2554                            &language_name,
 2555                            cx,
 2556                        );
 2557
 2558                        if let Some(state) = self.language_servers.get(&server_id)
 2559                            && let Ok(uri) = uri
 2560                        {
 2561                            state.add_workspace_folder(uri);
 2562                        };
 2563                        server_id
 2564                    }
 2565                })?;
 2566                let server_state = self.language_servers.get(&server_id)?;
 2567                if let LanguageServerState::Running {
 2568                    server, adapter, ..
 2569                } = server_state
 2570                {
 2571                    Some((server.clone(), adapter.clone()))
 2572                } else {
 2573                    None
 2574                }
 2575            })
 2576            .collect::<Vec<_>>();
 2577        for (server, adapter) in servers_and_adapters {
 2578            buffer_handle.update(cx, |buffer, cx| {
 2579                buffer.set_completion_triggers(
 2580                    server.server_id(),
 2581                    server
 2582                        .capabilities()
 2583                        .completion_provider
 2584                        .as_ref()
 2585                        .and_then(|provider| {
 2586                            provider
 2587                                .trigger_characters
 2588                                .as_ref()
 2589                                .map(|characters| characters.iter().cloned().collect())
 2590                        })
 2591                        .unwrap_or_default(),
 2592                    cx,
 2593                );
 2594            });
 2595
 2596            let snapshot = LspBufferSnapshot {
 2597                version: 0,
 2598                snapshot: initial_snapshot.clone(),
 2599            };
 2600
 2601            let mut registered = false;
 2602            self.buffer_snapshots
 2603                .entry(buffer_id)
 2604                .or_default()
 2605                .entry(server.server_id())
 2606                .or_insert_with(|| {
 2607                    registered = true;
 2608                    server.register_buffer(
 2609                        uri.clone(),
 2610                        adapter.language_id(&language.name()),
 2611                        0,
 2612                        initial_snapshot.text(),
 2613                    );
 2614
 2615                    vec![snapshot]
 2616                });
 2617
 2618            self.buffers_opened_in_servers
 2619                .entry(buffer_id)
 2620                .or_default()
 2621                .insert(server.server_id());
 2622            if registered {
 2623                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2624                    language_server_id: server.server_id(),
 2625                    name: None,
 2626                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2627                        proto::RegisteredForBuffer {
 2628                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2629                            buffer_id: buffer_id.to_proto(),
 2630                        },
 2631                    ),
 2632                });
 2633            }
 2634        }
 2635    }
 2636
 2637    fn reuse_existing_language_server<'lang_name>(
 2638        &self,
 2639        server_tree: &LanguageServerTree,
 2640        worktree: &Entity<Worktree>,
 2641        language_name: &'lang_name LanguageName,
 2642        cx: &mut App,
 2643    ) -> Option<(
 2644        Arc<LocalLspAdapterDelegate>,
 2645        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2646    )> {
 2647        if worktree.read(cx).is_visible() {
 2648            return None;
 2649        }
 2650
 2651        let worktree_store = self.worktree_store.read(cx);
 2652        let servers = server_tree
 2653            .instances
 2654            .iter()
 2655            .filter(|(worktree_id, _)| {
 2656                worktree_store
 2657                    .worktree_for_id(**worktree_id, cx)
 2658                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2659            })
 2660            .flat_map(|(worktree_id, servers)| {
 2661                servers
 2662                    .roots
 2663                    .iter()
 2664                    .flat_map(|(_, language_servers)| language_servers)
 2665                    .map(move |(_, (server_node, server_languages))| {
 2666                        (worktree_id, server_node, server_languages)
 2667                    })
 2668                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2669                    .map(|(worktree_id, server_node, _)| {
 2670                        (
 2671                            *worktree_id,
 2672                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2673                        )
 2674                    })
 2675            })
 2676            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2677                acc.entry(worktree_id)
 2678                    .or_insert_with(Vec::new)
 2679                    .push(server_node);
 2680                acc
 2681            })
 2682            .into_values()
 2683            .max_by_key(|servers| servers.len())?;
 2684
 2685        let worktree_id = worktree.read(cx).id();
 2686        let apply = move |tree: &mut LanguageServerTree| {
 2687            for server_node in &servers {
 2688                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2689            }
 2690            servers
 2691        };
 2692
 2693        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2694        Some((delegate, apply))
 2695    }
 2696
 2697    pub(crate) fn unregister_old_buffer_from_language_servers(
 2698        &mut self,
 2699        buffer: &Entity<Buffer>,
 2700        old_file: &File,
 2701        cx: &mut App,
 2702    ) {
 2703        let old_path = match old_file.as_local() {
 2704            Some(local) => local.abs_path(cx),
 2705            None => return,
 2706        };
 2707
 2708        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2709            debug_panic!("{old_path:?} is not parseable as an URI");
 2710            return;
 2711        };
 2712        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2713    }
 2714
 2715    pub(crate) fn unregister_buffer_from_language_servers(
 2716        &mut self,
 2717        buffer: &Entity<Buffer>,
 2718        file_url: &lsp::Uri,
 2719        cx: &mut App,
 2720    ) {
 2721        buffer.update(cx, |buffer, cx| {
 2722            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2723
 2724            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2725                if snapshots
 2726                    .as_mut()
 2727                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2728                {
 2729                    language_server.unregister_buffer(file_url.clone());
 2730                }
 2731            }
 2732        });
 2733    }
 2734
 2735    fn buffer_snapshot_for_lsp_version(
 2736        &mut self,
 2737        buffer: &Entity<Buffer>,
 2738        server_id: LanguageServerId,
 2739        version: Option<i32>,
 2740        cx: &App,
 2741    ) -> Result<TextBufferSnapshot> {
 2742        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2743
 2744        if let Some(version) = version {
 2745            let buffer_id = buffer.read(cx).remote_id();
 2746            let snapshots = if let Some(snapshots) = self
 2747                .buffer_snapshots
 2748                .get_mut(&buffer_id)
 2749                .and_then(|m| m.get_mut(&server_id))
 2750            {
 2751                snapshots
 2752            } else if version == 0 {
 2753                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2754                // We detect this case and treat it as if the version was `None`.
 2755                return Ok(buffer.read(cx).text_snapshot());
 2756            } else {
 2757                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2758            };
 2759
 2760            let found_snapshot = snapshots
 2761                    .binary_search_by_key(&version, |e| e.version)
 2762                    .map(|ix| snapshots[ix].snapshot.clone())
 2763                    .map_err(|_| {
 2764                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2765                    })?;
 2766
 2767            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2768            Ok(found_snapshot)
 2769        } else {
 2770            Ok((buffer.read(cx)).text_snapshot())
 2771        }
 2772    }
 2773
 2774    async fn get_server_code_actions_from_action_kinds(
 2775        lsp_store: &WeakEntity<LspStore>,
 2776        language_server_id: LanguageServerId,
 2777        code_action_kinds: Vec<lsp::CodeActionKind>,
 2778        buffer: &Entity<Buffer>,
 2779        cx: &mut AsyncApp,
 2780    ) -> Result<Vec<CodeAction>> {
 2781        let actions = lsp_store
 2782            .update(cx, move |this, cx| {
 2783                let request = GetCodeActions {
 2784                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2785                    kinds: Some(code_action_kinds),
 2786                };
 2787                let server = LanguageServerToQuery::Other(language_server_id);
 2788                this.request_lsp(buffer.clone(), server, request, cx)
 2789            })?
 2790            .await?;
 2791        Ok(actions)
 2792    }
 2793
 2794    pub async fn execute_code_actions_on_server(
 2795        lsp_store: &WeakEntity<LspStore>,
 2796        language_server: &Arc<LanguageServer>,
 2797
 2798        actions: Vec<CodeAction>,
 2799        push_to_history: bool,
 2800        project_transaction: &mut ProjectTransaction,
 2801        cx: &mut AsyncApp,
 2802    ) -> anyhow::Result<()> {
 2803        for mut action in actions {
 2804            Self::try_resolve_code_action(language_server, &mut action)
 2805                .await
 2806                .context("resolving a formatting code action")?;
 2807
 2808            if let Some(edit) = action.lsp_action.edit() {
 2809                if edit.changes.is_none() && edit.document_changes.is_none() {
 2810                    continue;
 2811                }
 2812
 2813                let new = Self::deserialize_workspace_edit(
 2814                    lsp_store.upgrade().context("project dropped")?,
 2815                    edit.clone(),
 2816                    push_to_history,
 2817                    language_server.clone(),
 2818                    cx,
 2819                )
 2820                .await?;
 2821                project_transaction.0.extend(new.0);
 2822            }
 2823
 2824            if let Some(command) = action.lsp_action.command() {
 2825                let server_capabilities = language_server.capabilities();
 2826                let available_commands = server_capabilities
 2827                    .execute_command_provider
 2828                    .as_ref()
 2829                    .map(|options| options.commands.as_slice())
 2830                    .unwrap_or_default();
 2831                if available_commands.contains(&command.command) {
 2832                    lsp_store.update(cx, |lsp_store, _| {
 2833                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2834                            mode.last_workspace_edits_by_language_server
 2835                                .remove(&language_server.server_id());
 2836                        }
 2837                    })?;
 2838
 2839                    language_server
 2840                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2841                            command: command.command.clone(),
 2842                            arguments: command.arguments.clone().unwrap_or_default(),
 2843                            ..Default::default()
 2844                        })
 2845                        .await
 2846                        .into_response()
 2847                        .context("execute command")?;
 2848
 2849                    lsp_store.update(cx, |this, _| {
 2850                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2851                            project_transaction.0.extend(
 2852                                mode.last_workspace_edits_by_language_server
 2853                                    .remove(&language_server.server_id())
 2854                                    .unwrap_or_default()
 2855                                    .0,
 2856                            )
 2857                        }
 2858                    })?;
 2859                } else {
 2860                    log::warn!(
 2861                        "Cannot execute a command {} not listed in the language server capabilities",
 2862                        command.command
 2863                    )
 2864                }
 2865            }
 2866        }
 2867        Ok(())
 2868    }
 2869
 2870    pub async fn deserialize_text_edits(
 2871        this: Entity<LspStore>,
 2872        buffer_to_edit: Entity<Buffer>,
 2873        edits: Vec<lsp::TextEdit>,
 2874        push_to_history: bool,
 2875        _: Arc<CachedLspAdapter>,
 2876        language_server: Arc<LanguageServer>,
 2877        cx: &mut AsyncApp,
 2878    ) -> Result<Option<Transaction>> {
 2879        let edits = this
 2880            .update(cx, |this, cx| {
 2881                this.as_local_mut().unwrap().edits_from_lsp(
 2882                    &buffer_to_edit,
 2883                    edits,
 2884                    language_server.server_id(),
 2885                    None,
 2886                    cx,
 2887                )
 2888            })?
 2889            .await?;
 2890
 2891        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2892            buffer.finalize_last_transaction();
 2893            buffer.start_transaction();
 2894            for (range, text) in edits {
 2895                buffer.edit([(range, text)], None, cx);
 2896            }
 2897
 2898            if buffer.end_transaction(cx).is_some() {
 2899                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2900                if !push_to_history {
 2901                    buffer.forget_transaction(transaction.id);
 2902                }
 2903                Some(transaction)
 2904            } else {
 2905                None
 2906            }
 2907        })?;
 2908
 2909        Ok(transaction)
 2910    }
 2911
 2912    #[allow(clippy::type_complexity)]
 2913    pub(crate) fn edits_from_lsp(
 2914        &mut self,
 2915        buffer: &Entity<Buffer>,
 2916        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2917        server_id: LanguageServerId,
 2918        version: Option<i32>,
 2919        cx: &mut Context<LspStore>,
 2920    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2921        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2922        cx.background_spawn(async move {
 2923            let snapshot = snapshot?;
 2924            let mut lsp_edits = lsp_edits
 2925                .into_iter()
 2926                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2927                .collect::<Vec<_>>();
 2928
 2929            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2930
 2931            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2932            let mut edits = Vec::new();
 2933            while let Some((range, mut new_text)) = lsp_edits.next() {
 2934                // Clip invalid ranges provided by the language server.
 2935                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2936                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2937
 2938                // Combine any LSP edits that are adjacent.
 2939                //
 2940                // Also, combine LSP edits that are separated from each other by only
 2941                // a newline. This is important because for some code actions,
 2942                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2943                // are separated by unchanged newline characters.
 2944                //
 2945                // In order for the diffing logic below to work properly, any edits that
 2946                // cancel each other out must be combined into one.
 2947                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2948                    if next_range.start.0 > range.end {
 2949                        if next_range.start.0.row > range.end.row + 1
 2950                            || next_range.start.0.column > 0
 2951                            || snapshot.clip_point_utf16(
 2952                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2953                                Bias::Left,
 2954                            ) > range.end
 2955                        {
 2956                            break;
 2957                        }
 2958                        new_text.push('\n');
 2959                    }
 2960                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2961                    new_text.push_str(next_text);
 2962                    lsp_edits.next();
 2963                }
 2964
 2965                // For multiline edits, perform a diff of the old and new text so that
 2966                // we can identify the changes more precisely, preserving the locations
 2967                // of any anchors positioned in the unchanged regions.
 2968                if range.end.row > range.start.row {
 2969                    let offset = range.start.to_offset(&snapshot);
 2970                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2971                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2972                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2973                        (
 2974                            snapshot.anchor_after(offset + range.start)
 2975                                ..snapshot.anchor_before(offset + range.end),
 2976                            replacement,
 2977                        )
 2978                    }));
 2979                } else if range.end == range.start {
 2980                    let anchor = snapshot.anchor_after(range.start);
 2981                    edits.push((anchor..anchor, new_text.into()));
 2982                } else {
 2983                    let edit_start = snapshot.anchor_after(range.start);
 2984                    let edit_end = snapshot.anchor_before(range.end);
 2985                    edits.push((edit_start..edit_end, new_text.into()));
 2986                }
 2987            }
 2988
 2989            Ok(edits)
 2990        })
 2991    }
 2992
 2993    pub(crate) async fn deserialize_workspace_edit(
 2994        this: Entity<LspStore>,
 2995        edit: lsp::WorkspaceEdit,
 2996        push_to_history: bool,
 2997        language_server: Arc<LanguageServer>,
 2998        cx: &mut AsyncApp,
 2999    ) -> Result<ProjectTransaction> {
 3000        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 3001
 3002        let mut operations = Vec::new();
 3003        if let Some(document_changes) = edit.document_changes {
 3004            match document_changes {
 3005                lsp::DocumentChanges::Edits(edits) => {
 3006                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3007                }
 3008                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3009            }
 3010        } else if let Some(changes) = edit.changes {
 3011            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3012                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3013                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3014                        uri,
 3015                        version: None,
 3016                    },
 3017                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3018                })
 3019            }));
 3020        }
 3021
 3022        let mut project_transaction = ProjectTransaction::default();
 3023        for operation in operations {
 3024            match operation {
 3025                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3026                    let abs_path = op
 3027                        .uri
 3028                        .to_file_path()
 3029                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3030
 3031                    if let Some(parent_path) = abs_path.parent() {
 3032                        fs.create_dir(parent_path).await?;
 3033                    }
 3034                    if abs_path.ends_with("/") {
 3035                        fs.create_dir(&abs_path).await?;
 3036                    } else {
 3037                        fs.create_file(
 3038                            &abs_path,
 3039                            op.options
 3040                                .map(|options| fs::CreateOptions {
 3041                                    overwrite: options.overwrite.unwrap_or(false),
 3042                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3043                                })
 3044                                .unwrap_or_default(),
 3045                        )
 3046                        .await?;
 3047                    }
 3048                }
 3049
 3050                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3051                    let source_abs_path = op
 3052                        .old_uri
 3053                        .to_file_path()
 3054                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3055                    let target_abs_path = op
 3056                        .new_uri
 3057                        .to_file_path()
 3058                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3059
 3060                    let options = fs::RenameOptions {
 3061                        overwrite: op
 3062                            .options
 3063                            .as_ref()
 3064                            .and_then(|options| options.overwrite)
 3065                            .unwrap_or(false),
 3066                        ignore_if_exists: op
 3067                            .options
 3068                            .as_ref()
 3069                            .and_then(|options| options.ignore_if_exists)
 3070                            .unwrap_or(false),
 3071                        create_parents: true,
 3072                    };
 3073
 3074                    fs.rename(&source_abs_path, &target_abs_path, options)
 3075                        .await?;
 3076                }
 3077
 3078                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3079                    let abs_path = op
 3080                        .uri
 3081                        .to_file_path()
 3082                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3083                    let options = op
 3084                        .options
 3085                        .map(|options| fs::RemoveOptions {
 3086                            recursive: options.recursive.unwrap_or(false),
 3087                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3088                        })
 3089                        .unwrap_or_default();
 3090                    if abs_path.ends_with("/") {
 3091                        fs.remove_dir(&abs_path, options).await?;
 3092                    } else {
 3093                        fs.remove_file(&abs_path, options).await?;
 3094                    }
 3095                }
 3096
 3097                lsp::DocumentChangeOperation::Edit(op) => {
 3098                    let buffer_to_edit = this
 3099                        .update(cx, |this, cx| {
 3100                            this.open_local_buffer_via_lsp(
 3101                                op.text_document.uri.clone(),
 3102                                language_server.server_id(),
 3103                                cx,
 3104                            )
 3105                        })?
 3106                        .await?;
 3107
 3108                    let edits = this
 3109                        .update(cx, |this, cx| {
 3110                            let path = buffer_to_edit.read(cx).project_path(cx);
 3111                            let active_entry = this.active_entry;
 3112                            let is_active_entry = path.is_some_and(|project_path| {
 3113                                this.worktree_store
 3114                                    .read(cx)
 3115                                    .entry_for_path(&project_path, cx)
 3116                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3117                            });
 3118                            let local = this.as_local_mut().unwrap();
 3119
 3120                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3121                            for edit in op.edits {
 3122                                match edit {
 3123                                    Edit::Plain(edit) => {
 3124                                        if !edits.contains(&edit) {
 3125                                            edits.push(edit)
 3126                                        }
 3127                                    }
 3128                                    Edit::Annotated(edit) => {
 3129                                        if !edits.contains(&edit.text_edit) {
 3130                                            edits.push(edit.text_edit)
 3131                                        }
 3132                                    }
 3133                                    Edit::Snippet(edit) => {
 3134                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3135                                        else {
 3136                                            continue;
 3137                                        };
 3138
 3139                                        if is_active_entry {
 3140                                            snippet_edits.push((edit.range, snippet));
 3141                                        } else {
 3142                                            // Since this buffer is not focused, apply a normal edit.
 3143                                            let new_edit = TextEdit {
 3144                                                range: edit.range,
 3145                                                new_text: snippet.text,
 3146                                            };
 3147                                            if !edits.contains(&new_edit) {
 3148                                                edits.push(new_edit);
 3149                                            }
 3150                                        }
 3151                                    }
 3152                                }
 3153                            }
 3154                            if !snippet_edits.is_empty() {
 3155                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3156                                let version = if let Some(buffer_version) = op.text_document.version
 3157                                {
 3158                                    local
 3159                                        .buffer_snapshot_for_lsp_version(
 3160                                            &buffer_to_edit,
 3161                                            language_server.server_id(),
 3162                                            Some(buffer_version),
 3163                                            cx,
 3164                                        )
 3165                                        .ok()
 3166                                        .map(|snapshot| snapshot.version)
 3167                                } else {
 3168                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3169                                };
 3170
 3171                                let most_recent_edit =
 3172                                    version.and_then(|version| version.most_recent());
 3173                                // Check if the edit that triggered that edit has been made by this participant.
 3174
 3175                                if let Some(most_recent_edit) = most_recent_edit {
 3176                                    cx.emit(LspStoreEvent::SnippetEdit {
 3177                                        buffer_id,
 3178                                        edits: snippet_edits,
 3179                                        most_recent_edit,
 3180                                    });
 3181                                }
 3182                            }
 3183
 3184                            local.edits_from_lsp(
 3185                                &buffer_to_edit,
 3186                                edits,
 3187                                language_server.server_id(),
 3188                                op.text_document.version,
 3189                                cx,
 3190                            )
 3191                        })?
 3192                        .await?;
 3193
 3194                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3195                        buffer.finalize_last_transaction();
 3196                        buffer.start_transaction();
 3197                        for (range, text) in edits {
 3198                            buffer.edit([(range, text)], None, cx);
 3199                        }
 3200
 3201                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3202                            if push_to_history {
 3203                                buffer.finalize_last_transaction();
 3204                                buffer.get_transaction(transaction_id).cloned()
 3205                            } else {
 3206                                buffer.forget_transaction(transaction_id)
 3207                            }
 3208                        })
 3209                    })?;
 3210                    if let Some(transaction) = transaction {
 3211                        project_transaction.0.insert(buffer_to_edit, transaction);
 3212                    }
 3213                }
 3214            }
 3215        }
 3216
 3217        Ok(project_transaction)
 3218    }
 3219
 3220    async fn on_lsp_workspace_edit(
 3221        this: WeakEntity<LspStore>,
 3222        params: lsp::ApplyWorkspaceEditParams,
 3223        server_id: LanguageServerId,
 3224        cx: &mut AsyncApp,
 3225    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3226        let this = this.upgrade().context("project project closed")?;
 3227        let language_server = this
 3228            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3229            .context("language server not found")?;
 3230        let transaction = Self::deserialize_workspace_edit(
 3231            this.clone(),
 3232            params.edit,
 3233            true,
 3234            language_server.clone(),
 3235            cx,
 3236        )
 3237        .await
 3238        .log_err();
 3239        this.update(cx, |this, _| {
 3240            if let Some(transaction) = transaction {
 3241                this.as_local_mut()
 3242                    .unwrap()
 3243                    .last_workspace_edits_by_language_server
 3244                    .insert(server_id, transaction);
 3245            }
 3246        })?;
 3247        Ok(lsp::ApplyWorkspaceEditResponse {
 3248            applied: true,
 3249            failed_change: None,
 3250            failure_reason: None,
 3251        })
 3252    }
 3253
 3254    fn remove_worktree(
 3255        &mut self,
 3256        id_to_remove: WorktreeId,
 3257        cx: &mut Context<LspStore>,
 3258    ) -> Vec<LanguageServerId> {
 3259        self.diagnostics.remove(&id_to_remove);
 3260        self.prettier_store.update(cx, |prettier_store, cx| {
 3261            prettier_store.remove_worktree(id_to_remove, cx);
 3262        });
 3263
 3264        let mut servers_to_remove = BTreeSet::default();
 3265        let mut servers_to_preserve = HashSet::default();
 3266        for (seed, state) in &self.language_server_ids {
 3267            if seed.worktree_id == id_to_remove {
 3268                servers_to_remove.insert(state.id);
 3269            } else {
 3270                servers_to_preserve.insert(state.id);
 3271            }
 3272        }
 3273        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3274        self.language_server_ids
 3275            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3276        for server_id_to_remove in &servers_to_remove {
 3277            self.language_server_watched_paths
 3278                .remove(server_id_to_remove);
 3279            self.language_server_paths_watched_for_rename
 3280                .remove(server_id_to_remove);
 3281            self.last_workspace_edits_by_language_server
 3282                .remove(server_id_to_remove);
 3283            self.language_servers.remove(server_id_to_remove);
 3284            self.buffer_pull_diagnostics_result_ids
 3285                .remove(server_id_to_remove);
 3286            self.workspace_pull_diagnostics_result_ids
 3287                .remove(server_id_to_remove);
 3288            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3289                buffer_servers.remove(server_id_to_remove);
 3290            }
 3291            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3292        }
 3293        servers_to_remove.into_iter().collect()
 3294    }
 3295
 3296    fn rebuild_watched_paths_inner<'a>(
 3297        &'a self,
 3298        language_server_id: LanguageServerId,
 3299        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3300        cx: &mut Context<LspStore>,
 3301    ) -> LanguageServerWatchedPathsBuilder {
 3302        let worktrees = self
 3303            .worktree_store
 3304            .read(cx)
 3305            .worktrees()
 3306            .filter_map(|worktree| {
 3307                self.language_servers_for_worktree(worktree.read(cx).id())
 3308                    .find(|server| server.server_id() == language_server_id)
 3309                    .map(|_| worktree)
 3310            })
 3311            .collect::<Vec<_>>();
 3312
 3313        let mut worktree_globs = HashMap::default();
 3314        let mut abs_globs = HashMap::default();
 3315        log::trace!(
 3316            "Processing new watcher paths for language server with id {}",
 3317            language_server_id
 3318        );
 3319
 3320        for watcher in watchers {
 3321            if let Some((worktree, literal_prefix, pattern)) =
 3322                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3323            {
 3324                worktree.update(cx, |worktree, _| {
 3325                    if let Some((tree, glob)) =
 3326                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3327                    {
 3328                        tree.add_path_prefix_to_scan(literal_prefix);
 3329                        worktree_globs
 3330                            .entry(tree.id())
 3331                            .or_insert_with(GlobSetBuilder::new)
 3332                            .add(glob);
 3333                    }
 3334                });
 3335            } else {
 3336                let (path, pattern) = match &watcher.glob_pattern {
 3337                    lsp::GlobPattern::String(s) => {
 3338                        let watcher_path = SanitizedPath::new(s);
 3339                        let path = glob_literal_prefix(watcher_path.as_path());
 3340                        let pattern = watcher_path
 3341                            .as_path()
 3342                            .strip_prefix(&path)
 3343                            .map(|p| p.to_string_lossy().into_owned())
 3344                            .unwrap_or_else(|e| {
 3345                                debug_panic!(
 3346                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3347                                    s,
 3348                                    path.display(),
 3349                                    e
 3350                                );
 3351                                watcher_path.as_path().to_string_lossy().into_owned()
 3352                            });
 3353                        (path, pattern)
 3354                    }
 3355                    lsp::GlobPattern::Relative(rp) => {
 3356                        let Ok(mut base_uri) = match &rp.base_uri {
 3357                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3358                            lsp::OneOf::Right(base_uri) => base_uri,
 3359                        }
 3360                        .to_file_path() else {
 3361                            continue;
 3362                        };
 3363
 3364                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3365                        let pattern = Path::new(&rp.pattern)
 3366                            .strip_prefix(&path)
 3367                            .map(|p| p.to_string_lossy().into_owned())
 3368                            .unwrap_or_else(|e| {
 3369                                debug_panic!(
 3370                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3371                                    rp.pattern,
 3372                                    path.display(),
 3373                                    e
 3374                                );
 3375                                rp.pattern.clone()
 3376                            });
 3377                        base_uri.push(path);
 3378                        (base_uri, pattern)
 3379                    }
 3380                };
 3381
 3382                if let Some(glob) = Glob::new(&pattern).log_err() {
 3383                    if !path
 3384                        .components()
 3385                        .any(|c| matches!(c, path::Component::Normal(_)))
 3386                    {
 3387                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3388                        // rather than adding a new watcher for `/`.
 3389                        for worktree in &worktrees {
 3390                            worktree_globs
 3391                                .entry(worktree.read(cx).id())
 3392                                .or_insert_with(GlobSetBuilder::new)
 3393                                .add(glob.clone());
 3394                        }
 3395                    } else {
 3396                        abs_globs
 3397                            .entry(path.into())
 3398                            .or_insert_with(GlobSetBuilder::new)
 3399                            .add(glob);
 3400                    }
 3401                }
 3402            }
 3403        }
 3404
 3405        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3406        for (worktree_id, builder) in worktree_globs {
 3407            if let Ok(globset) = builder.build() {
 3408                watch_builder.watch_worktree(worktree_id, globset);
 3409            }
 3410        }
 3411        for (abs_path, builder) in abs_globs {
 3412            if let Ok(globset) = builder.build() {
 3413                watch_builder.watch_abs_path(abs_path, globset);
 3414            }
 3415        }
 3416        watch_builder
 3417    }
 3418
 3419    fn worktree_and_path_for_file_watcher(
 3420        worktrees: &[Entity<Worktree>],
 3421        watcher: &FileSystemWatcher,
 3422        cx: &App,
 3423    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3424        worktrees.iter().find_map(|worktree| {
 3425            let tree = worktree.read(cx);
 3426            let worktree_root_path = tree.abs_path();
 3427            let path_style = tree.path_style();
 3428            match &watcher.glob_pattern {
 3429                lsp::GlobPattern::String(s) => {
 3430                    let watcher_path = SanitizedPath::new(s);
 3431                    let relative = watcher_path
 3432                        .as_path()
 3433                        .strip_prefix(&worktree_root_path)
 3434                        .ok()?;
 3435                    let literal_prefix = glob_literal_prefix(relative);
 3436                    Some((
 3437                        worktree.clone(),
 3438                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3439                        relative.to_string_lossy().into_owned(),
 3440                    ))
 3441                }
 3442                lsp::GlobPattern::Relative(rp) => {
 3443                    let base_uri = match &rp.base_uri {
 3444                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3445                        lsp::OneOf::Right(base_uri) => base_uri,
 3446                    }
 3447                    .to_file_path()
 3448                    .ok()?;
 3449                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3450                    let mut literal_prefix = relative.to_owned();
 3451                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3452                    Some((
 3453                        worktree.clone(),
 3454                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3455                        rp.pattern.clone(),
 3456                    ))
 3457                }
 3458            }
 3459        })
 3460    }
 3461
 3462    fn rebuild_watched_paths(
 3463        &mut self,
 3464        language_server_id: LanguageServerId,
 3465        cx: &mut Context<LspStore>,
 3466    ) {
 3467        let Some(registrations) = self
 3468            .language_server_dynamic_registrations
 3469            .get(&language_server_id)
 3470        else {
 3471            return;
 3472        };
 3473
 3474        let watch_builder = self.rebuild_watched_paths_inner(
 3475            language_server_id,
 3476            registrations.did_change_watched_files.values().flatten(),
 3477            cx,
 3478        );
 3479        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3480        self.language_server_watched_paths
 3481            .insert(language_server_id, watcher);
 3482
 3483        cx.notify();
 3484    }
 3485
 3486    fn on_lsp_did_change_watched_files(
 3487        &mut self,
 3488        language_server_id: LanguageServerId,
 3489        registration_id: &str,
 3490        params: DidChangeWatchedFilesRegistrationOptions,
 3491        cx: &mut Context<LspStore>,
 3492    ) {
 3493        let registrations = self
 3494            .language_server_dynamic_registrations
 3495            .entry(language_server_id)
 3496            .or_default();
 3497
 3498        registrations
 3499            .did_change_watched_files
 3500            .insert(registration_id.to_string(), params.watchers);
 3501
 3502        self.rebuild_watched_paths(language_server_id, cx);
 3503    }
 3504
 3505    fn on_lsp_unregister_did_change_watched_files(
 3506        &mut self,
 3507        language_server_id: LanguageServerId,
 3508        registration_id: &str,
 3509        cx: &mut Context<LspStore>,
 3510    ) {
 3511        let registrations = self
 3512            .language_server_dynamic_registrations
 3513            .entry(language_server_id)
 3514            .or_default();
 3515
 3516        if registrations
 3517            .did_change_watched_files
 3518            .remove(registration_id)
 3519            .is_some()
 3520        {
 3521            log::info!(
 3522                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3523                language_server_id,
 3524                registration_id
 3525            );
 3526        } else {
 3527            log::warn!(
 3528                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3529                language_server_id,
 3530                registration_id
 3531            );
 3532        }
 3533
 3534        self.rebuild_watched_paths(language_server_id, cx);
 3535    }
 3536
 3537    async fn initialization_options_for_adapter(
 3538        adapter: Arc<dyn LspAdapter>,
 3539        delegate: &Arc<dyn LspAdapterDelegate>,
 3540    ) -> Result<Option<serde_json::Value>> {
 3541        let Some(mut initialization_config) =
 3542            adapter.clone().initialization_options(delegate).await?
 3543        else {
 3544            return Ok(None);
 3545        };
 3546
 3547        for other_adapter in delegate.registered_lsp_adapters() {
 3548            if other_adapter.name() == adapter.name() {
 3549                continue;
 3550            }
 3551            if let Ok(Some(target_config)) = other_adapter
 3552                .clone()
 3553                .additional_initialization_options(adapter.name(), delegate)
 3554                .await
 3555            {
 3556                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3557            }
 3558        }
 3559
 3560        Ok(Some(initialization_config))
 3561    }
 3562
 3563    async fn workspace_configuration_for_adapter(
 3564        adapter: Arc<dyn LspAdapter>,
 3565        delegate: &Arc<dyn LspAdapterDelegate>,
 3566        toolchain: Option<Toolchain>,
 3567        requested_uri: Option<Uri>,
 3568        cx: &mut AsyncApp,
 3569    ) -> Result<serde_json::Value> {
 3570        let mut workspace_config = adapter
 3571            .clone()
 3572            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3573            .await?;
 3574
 3575        for other_adapter in delegate.registered_lsp_adapters() {
 3576            if other_adapter.name() == adapter.name() {
 3577                continue;
 3578            }
 3579            if let Ok(Some(target_config)) = other_adapter
 3580                .clone()
 3581                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3582                .await
 3583            {
 3584                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3585            }
 3586        }
 3587
 3588        Ok(workspace_config)
 3589    }
 3590
 3591    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3592        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3593            Some(server.clone())
 3594        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3595            Some(Arc::clone(server))
 3596        } else {
 3597            None
 3598        }
 3599    }
 3600}
 3601
 3602fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3603    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3604        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3605            language_server_id: server.server_id(),
 3606            name: Some(server.name()),
 3607            message: proto::update_language_server::Variant::MetadataUpdated(
 3608                proto::ServerMetadataUpdated {
 3609                    capabilities: Some(capabilities),
 3610                    binary: Some(proto::LanguageServerBinaryInfo {
 3611                        path: server.binary().path.to_string_lossy().into_owned(),
 3612                        arguments: server
 3613                            .binary()
 3614                            .arguments
 3615                            .iter()
 3616                            .map(|arg| arg.to_string_lossy().into_owned())
 3617                            .collect(),
 3618                    }),
 3619                    configuration: serde_json::to_string(server.configuration()).ok(),
 3620                    workspace_folders: server
 3621                        .workspace_folders()
 3622                        .iter()
 3623                        .map(|uri| uri.to_string())
 3624                        .collect(),
 3625                },
 3626            ),
 3627        });
 3628    }
 3629}
 3630
 3631#[derive(Debug)]
 3632pub struct FormattableBuffer {
 3633    handle: Entity<Buffer>,
 3634    abs_path: Option<PathBuf>,
 3635    env: Option<HashMap<String, String>>,
 3636    ranges: Option<Vec<Range<Anchor>>>,
 3637}
 3638
 3639pub struct RemoteLspStore {
 3640    upstream_client: Option<AnyProtoClient>,
 3641    upstream_project_id: u64,
 3642}
 3643
 3644pub(crate) enum LspStoreMode {
 3645    Local(LocalLspStore),   // ssh host and collab host
 3646    Remote(RemoteLspStore), // collab guest
 3647}
 3648
 3649impl LspStoreMode {
 3650    fn is_local(&self) -> bool {
 3651        matches!(self, LspStoreMode::Local(_))
 3652    }
 3653}
 3654
 3655pub struct LspStore {
 3656    mode: LspStoreMode,
 3657    last_formatting_failure: Option<String>,
 3658    downstream_client: Option<(AnyProtoClient, u64)>,
 3659    nonce: u128,
 3660    buffer_store: Entity<BufferStore>,
 3661    worktree_store: Entity<WorktreeStore>,
 3662    pub languages: Arc<LanguageRegistry>,
 3663    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3664    active_entry: Option<ProjectEntryId>,
 3665    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3666    _maintain_buffer_languages: Task<()>,
 3667    diagnostic_summaries:
 3668        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3669    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3670    lsp_data: HashMap<BufferId, BufferLspData>,
 3671    next_hint_id: Arc<AtomicUsize>,
 3672}
 3673
 3674#[derive(Debug)]
 3675pub struct BufferLspData {
 3676    buffer_version: Global,
 3677    document_colors: Option<DocumentColorData>,
 3678    code_lens: Option<CodeLensData>,
 3679    inlay_hints: BufferInlayHints,
 3680    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3681    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3682}
 3683
 3684#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3685struct LspKey {
 3686    request_type: TypeId,
 3687    server_queried: Option<LanguageServerId>,
 3688}
 3689
 3690impl BufferLspData {
 3691    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3692        Self {
 3693            buffer_version: buffer.read(cx).version(),
 3694            document_colors: None,
 3695            code_lens: None,
 3696            inlay_hints: BufferInlayHints::new(buffer, cx),
 3697            lsp_requests: HashMap::default(),
 3698            chunk_lsp_requests: HashMap::default(),
 3699        }
 3700    }
 3701
 3702    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3703        if let Some(document_colors) = &mut self.document_colors {
 3704            document_colors.colors.remove(&for_server);
 3705            document_colors.cache_version += 1;
 3706        }
 3707
 3708        if let Some(code_lens) = &mut self.code_lens {
 3709            code_lens.lens.remove(&for_server);
 3710        }
 3711
 3712        self.inlay_hints.remove_server_data(for_server);
 3713    }
 3714
 3715    #[cfg(any(test, feature = "test-support"))]
 3716    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3717        &self.inlay_hints
 3718    }
 3719}
 3720
 3721#[derive(Debug, Default, Clone)]
 3722pub struct DocumentColors {
 3723    pub colors: HashSet<DocumentColor>,
 3724    pub cache_version: Option<usize>,
 3725}
 3726
 3727type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3728type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3729
 3730#[derive(Debug, Default)]
 3731struct DocumentColorData {
 3732    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3733    cache_version: usize,
 3734    colors_update: Option<(Global, DocumentColorTask)>,
 3735}
 3736
 3737#[derive(Debug, Default)]
 3738struct CodeLensData {
 3739    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3740    update: Option<(Global, CodeLensTask)>,
 3741}
 3742
 3743#[derive(Debug)]
 3744pub enum LspStoreEvent {
 3745    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3746    LanguageServerRemoved(LanguageServerId),
 3747    LanguageServerUpdate {
 3748        language_server_id: LanguageServerId,
 3749        name: Option<LanguageServerName>,
 3750        message: proto::update_language_server::Variant,
 3751    },
 3752    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3753    LanguageServerPrompt(LanguageServerPromptRequest),
 3754    LanguageDetected {
 3755        buffer: Entity<Buffer>,
 3756        new_language: Option<Arc<Language>>,
 3757    },
 3758    Notification(String),
 3759    RefreshInlayHints {
 3760        server_id: LanguageServerId,
 3761        request_id: Option<usize>,
 3762    },
 3763    RefreshCodeLens,
 3764    DiagnosticsUpdated {
 3765        server_id: LanguageServerId,
 3766        paths: Vec<ProjectPath>,
 3767    },
 3768    DiskBasedDiagnosticsStarted {
 3769        language_server_id: LanguageServerId,
 3770    },
 3771    DiskBasedDiagnosticsFinished {
 3772        language_server_id: LanguageServerId,
 3773    },
 3774    SnippetEdit {
 3775        buffer_id: BufferId,
 3776        edits: Vec<(lsp::Range, Snippet)>,
 3777        most_recent_edit: clock::Lamport,
 3778    },
 3779}
 3780
 3781#[derive(Clone, Debug, Serialize)]
 3782pub struct LanguageServerStatus {
 3783    pub name: LanguageServerName,
 3784    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3785    pub has_pending_diagnostic_updates: bool,
 3786    pub progress_tokens: HashSet<ProgressToken>,
 3787    pub worktree: Option<WorktreeId>,
 3788    pub binary: Option<LanguageServerBinary>,
 3789    pub configuration: Option<Value>,
 3790    pub workspace_folders: BTreeSet<Uri>,
 3791}
 3792
 3793#[derive(Clone, Debug)]
 3794struct CoreSymbol {
 3795    pub language_server_name: LanguageServerName,
 3796    pub source_worktree_id: WorktreeId,
 3797    pub source_language_server_id: LanguageServerId,
 3798    pub path: SymbolLocation,
 3799    pub name: String,
 3800    pub kind: lsp::SymbolKind,
 3801    pub range: Range<Unclipped<PointUtf16>>,
 3802}
 3803
 3804#[derive(Clone, Debug, PartialEq, Eq)]
 3805pub enum SymbolLocation {
 3806    InProject(ProjectPath),
 3807    OutsideProject {
 3808        abs_path: Arc<Path>,
 3809        signature: [u8; 32],
 3810    },
 3811}
 3812
 3813impl SymbolLocation {
 3814    fn file_name(&self) -> Option<&str> {
 3815        match self {
 3816            Self::InProject(path) => path.path.file_name(),
 3817            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3818        }
 3819    }
 3820}
 3821
 3822impl LspStore {
 3823    pub fn init(client: &AnyProtoClient) {
 3824        client.add_entity_request_handler(Self::handle_lsp_query);
 3825        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3826        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3827        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3828        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3829        client.add_entity_message_handler(Self::handle_start_language_server);
 3830        client.add_entity_message_handler(Self::handle_update_language_server);
 3831        client.add_entity_message_handler(Self::handle_language_server_log);
 3832        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3833        client.add_entity_request_handler(Self::handle_format_buffers);
 3834        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3835        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3836        client.add_entity_request_handler(Self::handle_apply_code_action);
 3837        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3838        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3839        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3840        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3841        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3842        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3843        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3844        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3845        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3846        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3847        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3848        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3849        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3850        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3851        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3852        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3853        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3854
 3855        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3856        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3857        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3858        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3859        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3860        client.add_entity_request_handler(
 3861            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3862        );
 3863        client.add_entity_request_handler(
 3864            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3865        );
 3866        client.add_entity_request_handler(
 3867            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3868        );
 3869    }
 3870
 3871    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3872        match &self.mode {
 3873            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3874            _ => None,
 3875        }
 3876    }
 3877
 3878    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3879        match &self.mode {
 3880            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3881            _ => None,
 3882        }
 3883    }
 3884
 3885    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3886        match &mut self.mode {
 3887            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3888            _ => None,
 3889        }
 3890    }
 3891
 3892    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3893        match &self.mode {
 3894            LspStoreMode::Remote(RemoteLspStore {
 3895                upstream_client: Some(upstream_client),
 3896                upstream_project_id,
 3897                ..
 3898            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3899
 3900            LspStoreMode::Remote(RemoteLspStore {
 3901                upstream_client: None,
 3902                ..
 3903            }) => None,
 3904            LspStoreMode::Local(_) => None,
 3905        }
 3906    }
 3907
 3908    pub fn new_local(
 3909        buffer_store: Entity<BufferStore>,
 3910        worktree_store: Entity<WorktreeStore>,
 3911        prettier_store: Entity<PrettierStore>,
 3912        toolchain_store: Entity<LocalToolchainStore>,
 3913        environment: Entity<ProjectEnvironment>,
 3914        manifest_tree: Entity<ManifestTree>,
 3915        languages: Arc<LanguageRegistry>,
 3916        http_client: Arc<dyn HttpClient>,
 3917        fs: Arc<dyn Fs>,
 3918        cx: &mut Context<Self>,
 3919    ) -> Self {
 3920        let yarn = YarnPathStore::new(fs.clone(), cx);
 3921        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3922            .detach();
 3923        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3924            .detach();
 3925        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3926            .detach();
 3927        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3928            .detach();
 3929        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3930            .detach();
 3931        subscribe_to_binary_statuses(&languages, cx).detach();
 3932
 3933        let _maintain_workspace_config = {
 3934            let (sender, receiver) = watch::channel();
 3935            (Self::maintain_workspace_config(receiver, cx), sender)
 3936        };
 3937
 3938        Self {
 3939            mode: LspStoreMode::Local(LocalLspStore {
 3940                weak: cx.weak_entity(),
 3941                worktree_store: worktree_store.clone(),
 3942
 3943                supplementary_language_servers: Default::default(),
 3944                languages: languages.clone(),
 3945                language_server_ids: Default::default(),
 3946                language_servers: Default::default(),
 3947                last_workspace_edits_by_language_server: Default::default(),
 3948                language_server_watched_paths: Default::default(),
 3949                language_server_paths_watched_for_rename: Default::default(),
 3950                language_server_dynamic_registrations: Default::default(),
 3951                buffers_being_formatted: Default::default(),
 3952                buffer_snapshots: Default::default(),
 3953                prettier_store,
 3954                environment,
 3955                http_client,
 3956                fs,
 3957                yarn,
 3958                next_diagnostic_group_id: Default::default(),
 3959                diagnostics: Default::default(),
 3960                _subscription: cx.on_app_quit(|this, cx| {
 3961                    this.as_local_mut()
 3962                        .unwrap()
 3963                        .shutdown_language_servers_on_quit(cx)
 3964                }),
 3965                lsp_tree: LanguageServerTree::new(
 3966                    manifest_tree,
 3967                    languages.clone(),
 3968                    toolchain_store.clone(),
 3969                ),
 3970                toolchain_store,
 3971                registered_buffers: HashMap::default(),
 3972                buffers_opened_in_servers: HashMap::default(),
 3973                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3974                workspace_pull_diagnostics_result_ids: HashMap::default(),
 3975                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3976                    .manifest_file_names(),
 3977            }),
 3978            last_formatting_failure: None,
 3979            downstream_client: None,
 3980            buffer_store,
 3981            worktree_store,
 3982            languages: languages.clone(),
 3983            language_server_statuses: Default::default(),
 3984            nonce: StdRng::from_os_rng().random(),
 3985            diagnostic_summaries: HashMap::default(),
 3986            lsp_server_capabilities: HashMap::default(),
 3987            lsp_data: HashMap::default(),
 3988            next_hint_id: Arc::default(),
 3989            active_entry: None,
 3990            _maintain_workspace_config,
 3991            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3992        }
 3993    }
 3994
 3995    fn send_lsp_proto_request<R: LspCommand>(
 3996        &self,
 3997        buffer: Entity<Buffer>,
 3998        client: AnyProtoClient,
 3999        upstream_project_id: u64,
 4000        request: R,
 4001        cx: &mut Context<LspStore>,
 4002    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4003        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4004            return Task::ready(Ok(R::Response::default()));
 4005        }
 4006        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4007        cx.spawn(async move |this, cx| {
 4008            let response = client.request(message).await?;
 4009            let this = this.upgrade().context("project dropped")?;
 4010            request
 4011                .response_from_proto(response, this, buffer, cx.clone())
 4012                .await
 4013        })
 4014    }
 4015
 4016    pub(super) fn new_remote(
 4017        buffer_store: Entity<BufferStore>,
 4018        worktree_store: Entity<WorktreeStore>,
 4019        languages: Arc<LanguageRegistry>,
 4020        upstream_client: AnyProtoClient,
 4021        project_id: u64,
 4022        cx: &mut Context<Self>,
 4023    ) -> Self {
 4024        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4025            .detach();
 4026        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4027            .detach();
 4028        subscribe_to_binary_statuses(&languages, cx).detach();
 4029        let _maintain_workspace_config = {
 4030            let (sender, receiver) = watch::channel();
 4031            (Self::maintain_workspace_config(receiver, cx), sender)
 4032        };
 4033        Self {
 4034            mode: LspStoreMode::Remote(RemoteLspStore {
 4035                upstream_client: Some(upstream_client),
 4036                upstream_project_id: project_id,
 4037            }),
 4038            downstream_client: None,
 4039            last_formatting_failure: None,
 4040            buffer_store,
 4041            worktree_store,
 4042            languages: languages.clone(),
 4043            language_server_statuses: Default::default(),
 4044            nonce: StdRng::from_os_rng().random(),
 4045            diagnostic_summaries: HashMap::default(),
 4046            lsp_server_capabilities: HashMap::default(),
 4047            next_hint_id: Arc::default(),
 4048            lsp_data: HashMap::default(),
 4049            active_entry: None,
 4050
 4051            _maintain_workspace_config,
 4052            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4053        }
 4054    }
 4055
 4056    fn on_buffer_store_event(
 4057        &mut self,
 4058        _: Entity<BufferStore>,
 4059        event: &BufferStoreEvent,
 4060        cx: &mut Context<Self>,
 4061    ) {
 4062        match event {
 4063            BufferStoreEvent::BufferAdded(buffer) => {
 4064                self.on_buffer_added(buffer, cx).log_err();
 4065            }
 4066            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4067                let buffer_id = buffer.read(cx).remote_id();
 4068                if let Some(local) = self.as_local_mut()
 4069                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4070                {
 4071                    local.reset_buffer(buffer, old_file, cx);
 4072
 4073                    if local.registered_buffers.contains_key(&buffer_id) {
 4074                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4075                    }
 4076                }
 4077
 4078                self.detect_language_for_buffer(buffer, cx);
 4079                if let Some(local) = self.as_local_mut() {
 4080                    local.initialize_buffer(buffer, cx);
 4081                    if local.registered_buffers.contains_key(&buffer_id) {
 4082                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4083                    }
 4084                }
 4085            }
 4086            _ => {}
 4087        }
 4088    }
 4089
 4090    fn on_worktree_store_event(
 4091        &mut self,
 4092        _: Entity<WorktreeStore>,
 4093        event: &WorktreeStoreEvent,
 4094        cx: &mut Context<Self>,
 4095    ) {
 4096        match event {
 4097            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4098                if !worktree.read(cx).is_local() {
 4099                    return;
 4100                }
 4101                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4102                    worktree::Event::UpdatedEntries(changes) => {
 4103                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4104                    }
 4105                    worktree::Event::UpdatedGitRepositories(_)
 4106                    | worktree::Event::DeletedEntry(_) => {}
 4107                })
 4108                .detach()
 4109            }
 4110            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4111            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4112                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4113            }
 4114            WorktreeStoreEvent::WorktreeReleased(..)
 4115            | WorktreeStoreEvent::WorktreeOrderChanged
 4116            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4117            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4118            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4119        }
 4120    }
 4121
 4122    fn on_prettier_store_event(
 4123        &mut self,
 4124        _: Entity<PrettierStore>,
 4125        event: &PrettierStoreEvent,
 4126        cx: &mut Context<Self>,
 4127    ) {
 4128        match event {
 4129            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4130                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4131            }
 4132            PrettierStoreEvent::LanguageServerAdded {
 4133                new_server_id,
 4134                name,
 4135                prettier_server,
 4136            } => {
 4137                self.register_supplementary_language_server(
 4138                    *new_server_id,
 4139                    name.clone(),
 4140                    prettier_server.clone(),
 4141                    cx,
 4142                );
 4143            }
 4144        }
 4145    }
 4146
 4147    fn on_toolchain_store_event(
 4148        &mut self,
 4149        _: Entity<LocalToolchainStore>,
 4150        event: &ToolchainStoreEvent,
 4151        _: &mut Context<Self>,
 4152    ) {
 4153        if let ToolchainStoreEvent::ToolchainActivated = event {
 4154            self.request_workspace_config_refresh()
 4155        }
 4156    }
 4157
 4158    fn request_workspace_config_refresh(&mut self) {
 4159        *self._maintain_workspace_config.1.borrow_mut() = ();
 4160    }
 4161
 4162    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4163        self.as_local().map(|local| local.prettier_store.clone())
 4164    }
 4165
 4166    fn on_buffer_event(
 4167        &mut self,
 4168        buffer: Entity<Buffer>,
 4169        event: &language::BufferEvent,
 4170        cx: &mut Context<Self>,
 4171    ) {
 4172        match event {
 4173            language::BufferEvent::Edited => {
 4174                self.on_buffer_edited(buffer, cx);
 4175            }
 4176
 4177            language::BufferEvent::Saved => {
 4178                self.on_buffer_saved(buffer, cx);
 4179            }
 4180
 4181            _ => {}
 4182        }
 4183    }
 4184
 4185    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4186        buffer
 4187            .read(cx)
 4188            .set_language_registry(self.languages.clone());
 4189
 4190        cx.subscribe(buffer, |this, buffer, event, cx| {
 4191            this.on_buffer_event(buffer, event, cx);
 4192        })
 4193        .detach();
 4194
 4195        self.detect_language_for_buffer(buffer, cx);
 4196        if let Some(local) = self.as_local_mut() {
 4197            local.initialize_buffer(buffer, cx);
 4198        }
 4199
 4200        Ok(())
 4201    }
 4202
 4203    pub(crate) fn register_buffer_with_language_servers(
 4204        &mut self,
 4205        buffer: &Entity<Buffer>,
 4206        only_register_servers: HashSet<LanguageServerSelector>,
 4207        ignore_refcounts: bool,
 4208        cx: &mut Context<Self>,
 4209    ) -> OpenLspBufferHandle {
 4210        let buffer_id = buffer.read(cx).remote_id();
 4211        let handle = cx.new(|_| buffer.clone());
 4212        if let Some(local) = self.as_local_mut() {
 4213            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4214            if !ignore_refcounts {
 4215                *refcount += 1;
 4216            }
 4217
 4218            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4219            // 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
 4220            // 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
 4221            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4222            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4223                return handle;
 4224            };
 4225            if !file.is_local() {
 4226                return handle;
 4227            }
 4228
 4229            if ignore_refcounts || *refcount == 1 {
 4230                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4231            }
 4232            if !ignore_refcounts {
 4233                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4234                    let refcount = {
 4235                        let local = lsp_store.as_local_mut().unwrap();
 4236                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4237                            debug_panic!("bad refcounting");
 4238                            return;
 4239                        };
 4240
 4241                        *refcount -= 1;
 4242                        *refcount
 4243                    };
 4244                    if refcount == 0 {
 4245                        lsp_store.lsp_data.remove(&buffer_id);
 4246                        let local = lsp_store.as_local_mut().unwrap();
 4247                        local.registered_buffers.remove(&buffer_id);
 4248
 4249                        local.buffers_opened_in_servers.remove(&buffer_id);
 4250                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4251                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4252
 4253                            let buffer_abs_path = file.abs_path(cx);
 4254                            for (_, buffer_pull_diagnostics_result_ids) in
 4255                                &mut local.buffer_pull_diagnostics_result_ids
 4256                            {
 4257                                buffer_pull_diagnostics_result_ids.retain(
 4258                                    |_, buffer_result_ids| {
 4259                                        buffer_result_ids.remove(&buffer_abs_path);
 4260                                        !buffer_result_ids.is_empty()
 4261                                    },
 4262                                );
 4263                            }
 4264
 4265                            let diagnostic_updates = local
 4266                                .language_servers
 4267                                .keys()
 4268                                .cloned()
 4269                                .map(|server_id| DocumentDiagnosticsUpdate {
 4270                                    diagnostics: DocumentDiagnostics {
 4271                                        document_abs_path: buffer_abs_path.clone(),
 4272                                        version: None,
 4273                                        diagnostics: Vec::new(),
 4274                                    },
 4275                                    result_id: None,
 4276                                    registration_id: None,
 4277                                    server_id: server_id,
 4278                                    disk_based_sources: Cow::Borrowed(&[]),
 4279                                })
 4280                                .collect::<Vec<_>>();
 4281
 4282                            lsp_store
 4283                                .merge_diagnostic_entries(
 4284                                    diagnostic_updates,
 4285                                    |_, diagnostic, _| {
 4286                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4287                                    },
 4288                                    cx,
 4289                                )
 4290                                .context("Clearing diagnostics for the closed buffer")
 4291                                .log_err();
 4292                        }
 4293                    }
 4294                })
 4295                .detach();
 4296            }
 4297        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4298            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4299            cx.background_spawn(async move {
 4300                upstream_client
 4301                    .request(proto::RegisterBufferWithLanguageServers {
 4302                        project_id: upstream_project_id,
 4303                        buffer_id,
 4304                        only_servers: only_register_servers
 4305                            .into_iter()
 4306                            .map(|selector| {
 4307                                let selector = match selector {
 4308                                    LanguageServerSelector::Id(language_server_id) => {
 4309                                        proto::language_server_selector::Selector::ServerId(
 4310                                            language_server_id.to_proto(),
 4311                                        )
 4312                                    }
 4313                                    LanguageServerSelector::Name(language_server_name) => {
 4314                                        proto::language_server_selector::Selector::Name(
 4315                                            language_server_name.to_string(),
 4316                                        )
 4317                                    }
 4318                                };
 4319                                proto::LanguageServerSelector {
 4320                                    selector: Some(selector),
 4321                                }
 4322                            })
 4323                            .collect(),
 4324                    })
 4325                    .await
 4326            })
 4327            .detach();
 4328        } else {
 4329            // Our remote connection got closed
 4330        }
 4331        handle
 4332    }
 4333
 4334    fn maintain_buffer_languages(
 4335        languages: Arc<LanguageRegistry>,
 4336        cx: &mut Context<Self>,
 4337    ) -> Task<()> {
 4338        let mut subscription = languages.subscribe();
 4339        let mut prev_reload_count = languages.reload_count();
 4340        cx.spawn(async move |this, cx| {
 4341            while let Some(()) = subscription.next().await {
 4342                if let Some(this) = this.upgrade() {
 4343                    // If the language registry has been reloaded, then remove and
 4344                    // re-assign the languages on all open buffers.
 4345                    let reload_count = languages.reload_count();
 4346                    if reload_count > prev_reload_count {
 4347                        prev_reload_count = reload_count;
 4348                        this.update(cx, |this, cx| {
 4349                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4350                                for buffer in buffer_store.buffers() {
 4351                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4352                                    {
 4353                                        buffer.update(cx, |buffer, cx| {
 4354                                            buffer.set_language_async(None, cx)
 4355                                        });
 4356                                        if let Some(local) = this.as_local_mut() {
 4357                                            local.reset_buffer(&buffer, &f, cx);
 4358
 4359                                            if local
 4360                                                .registered_buffers
 4361                                                .contains_key(&buffer.read(cx).remote_id())
 4362                                                && let Some(file_url) =
 4363                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4364                                            {
 4365                                                local.unregister_buffer_from_language_servers(
 4366                                                    &buffer, &file_url, cx,
 4367                                                );
 4368                                            }
 4369                                        }
 4370                                    }
 4371                                }
 4372                            });
 4373                        })
 4374                        .ok();
 4375                    }
 4376
 4377                    this.update(cx, |this, cx| {
 4378                        let mut plain_text_buffers = Vec::new();
 4379                        let mut buffers_with_unknown_injections = Vec::new();
 4380                        for handle in this.buffer_store.read(cx).buffers() {
 4381                            let buffer = handle.read(cx);
 4382                            if buffer.language().is_none()
 4383                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4384                            {
 4385                                plain_text_buffers.push(handle);
 4386                            } else if buffer.contains_unknown_injections() {
 4387                                buffers_with_unknown_injections.push(handle);
 4388                            }
 4389                        }
 4390
 4391                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4392                        // and reused later in the invisible worktrees.
 4393                        plain_text_buffers.sort_by_key(|buffer| {
 4394                            Reverse(
 4395                                File::from_dyn(buffer.read(cx).file())
 4396                                    .map(|file| file.worktree.read(cx).is_visible()),
 4397                            )
 4398                        });
 4399
 4400                        for buffer in plain_text_buffers {
 4401                            this.detect_language_for_buffer(&buffer, cx);
 4402                            if let Some(local) = this.as_local_mut() {
 4403                                local.initialize_buffer(&buffer, cx);
 4404                                if local
 4405                                    .registered_buffers
 4406                                    .contains_key(&buffer.read(cx).remote_id())
 4407                                {
 4408                                    local.register_buffer_with_language_servers(
 4409                                        &buffer,
 4410                                        HashSet::default(),
 4411                                        cx,
 4412                                    );
 4413                                }
 4414                            }
 4415                        }
 4416
 4417                        for buffer in buffers_with_unknown_injections {
 4418                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4419                        }
 4420                    })
 4421                    .ok();
 4422                }
 4423            }
 4424        })
 4425    }
 4426
 4427    fn detect_language_for_buffer(
 4428        &mut self,
 4429        buffer_handle: &Entity<Buffer>,
 4430        cx: &mut Context<Self>,
 4431    ) -> Option<language::AvailableLanguage> {
 4432        // If the buffer has a language, set it and start the language server if we haven't already.
 4433        let buffer = buffer_handle.read(cx);
 4434        let file = buffer.file()?;
 4435
 4436        let content = buffer.as_rope();
 4437        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4438        if let Some(available_language) = &available_language {
 4439            if let Some(Ok(Ok(new_language))) = self
 4440                .languages
 4441                .load_language(available_language)
 4442                .now_or_never()
 4443            {
 4444                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4445            }
 4446        } else {
 4447            cx.emit(LspStoreEvent::LanguageDetected {
 4448                buffer: buffer_handle.clone(),
 4449                new_language: None,
 4450            });
 4451        }
 4452
 4453        available_language
 4454    }
 4455
 4456    pub(crate) fn set_language_for_buffer(
 4457        &mut self,
 4458        buffer_entity: &Entity<Buffer>,
 4459        new_language: Arc<Language>,
 4460        cx: &mut Context<Self>,
 4461    ) {
 4462        let buffer = buffer_entity.read(cx);
 4463        let buffer_file = buffer.file().cloned();
 4464        let buffer_id = buffer.remote_id();
 4465        if let Some(local_store) = self.as_local_mut()
 4466            && local_store.registered_buffers.contains_key(&buffer_id)
 4467            && let Some(abs_path) =
 4468                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4469            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4470        {
 4471            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4472        }
 4473        buffer_entity.update(cx, |buffer, cx| {
 4474            if buffer
 4475                .language()
 4476                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4477            {
 4478                buffer.set_language_async(Some(new_language.clone()), cx);
 4479            }
 4480        });
 4481
 4482        let settings =
 4483            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4484        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4485
 4486        let worktree_id = if let Some(file) = buffer_file {
 4487            let worktree = file.worktree.clone();
 4488
 4489            if let Some(local) = self.as_local_mut()
 4490                && local.registered_buffers.contains_key(&buffer_id)
 4491            {
 4492                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4493            }
 4494            Some(worktree.read(cx).id())
 4495        } else {
 4496            None
 4497        };
 4498
 4499        if settings.prettier.allowed
 4500            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4501        {
 4502            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4503            if let Some(prettier_store) = prettier_store {
 4504                prettier_store.update(cx, |prettier_store, cx| {
 4505                    prettier_store.install_default_prettier(
 4506                        worktree_id,
 4507                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4508                        cx,
 4509                    )
 4510                })
 4511            }
 4512        }
 4513
 4514        cx.emit(LspStoreEvent::LanguageDetected {
 4515            buffer: buffer_entity.clone(),
 4516            new_language: Some(new_language),
 4517        })
 4518    }
 4519
 4520    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4521        self.buffer_store.clone()
 4522    }
 4523
 4524    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4525        self.active_entry = active_entry;
 4526    }
 4527
 4528    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4529        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4530            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4531        {
 4532            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4533                summaries
 4534                    .iter()
 4535                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4536            });
 4537            if let Some(summary) = summaries.next() {
 4538                client
 4539                    .send(proto::UpdateDiagnosticSummary {
 4540                        project_id: downstream_project_id,
 4541                        worktree_id: worktree.id().to_proto(),
 4542                        summary: Some(summary),
 4543                        more_summaries: summaries.collect(),
 4544                    })
 4545                    .log_err();
 4546            }
 4547        }
 4548    }
 4549
 4550    fn is_capable_for_proto_request<R>(
 4551        &self,
 4552        buffer: &Entity<Buffer>,
 4553        request: &R,
 4554        cx: &App,
 4555    ) -> bool
 4556    where
 4557        R: LspCommand,
 4558    {
 4559        self.check_if_capable_for_proto_request(
 4560            buffer,
 4561            |capabilities| {
 4562                request.check_capabilities(AdapterServerCapabilities {
 4563                    server_capabilities: capabilities.clone(),
 4564                    code_action_kinds: None,
 4565                })
 4566            },
 4567            cx,
 4568        )
 4569    }
 4570
 4571    fn check_if_capable_for_proto_request<F>(
 4572        &self,
 4573        buffer: &Entity<Buffer>,
 4574        check: F,
 4575        cx: &App,
 4576    ) -> bool
 4577    where
 4578        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4579    {
 4580        let Some(language) = buffer.read(cx).language().cloned() else {
 4581            return false;
 4582        };
 4583        let relevant_language_servers = self
 4584            .languages
 4585            .lsp_adapters(&language.name())
 4586            .into_iter()
 4587            .map(|lsp_adapter| lsp_adapter.name())
 4588            .collect::<HashSet<_>>();
 4589        self.language_server_statuses
 4590            .iter()
 4591            .filter_map(|(server_id, server_status)| {
 4592                relevant_language_servers
 4593                    .contains(&server_status.name)
 4594                    .then_some(server_id)
 4595            })
 4596            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4597            .any(check)
 4598    }
 4599
 4600    fn all_capable_for_proto_request<F>(
 4601        &self,
 4602        buffer: &Entity<Buffer>,
 4603        mut check: F,
 4604        cx: &App,
 4605    ) -> Vec<lsp::LanguageServerId>
 4606    where
 4607        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4608    {
 4609        let Some(language) = buffer.read(cx).language().cloned() else {
 4610            return Vec::default();
 4611        };
 4612        let relevant_language_servers = self
 4613            .languages
 4614            .lsp_adapters(&language.name())
 4615            .into_iter()
 4616            .map(|lsp_adapter| lsp_adapter.name())
 4617            .collect::<HashSet<_>>();
 4618        self.language_server_statuses
 4619            .iter()
 4620            .filter_map(|(server_id, server_status)| {
 4621                relevant_language_servers
 4622                    .contains(&server_status.name)
 4623                    .then_some((server_id, &server_status.name))
 4624            })
 4625            .filter_map(|(server_id, server_name)| {
 4626                self.lsp_server_capabilities
 4627                    .get(server_id)
 4628                    .map(|c| (server_id, server_name, c))
 4629            })
 4630            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4631            .map(|(server_id, _, _)| *server_id)
 4632            .collect()
 4633    }
 4634
 4635    pub fn request_lsp<R>(
 4636        &mut self,
 4637        buffer: Entity<Buffer>,
 4638        server: LanguageServerToQuery,
 4639        request: R,
 4640        cx: &mut Context<Self>,
 4641    ) -> Task<Result<R::Response>>
 4642    where
 4643        R: LspCommand,
 4644        <R::LspRequest as lsp::request::Request>::Result: Send,
 4645        <R::LspRequest as lsp::request::Request>::Params: Send,
 4646    {
 4647        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4648            return self.send_lsp_proto_request(
 4649                buffer,
 4650                upstream_client,
 4651                upstream_project_id,
 4652                request,
 4653                cx,
 4654            );
 4655        }
 4656
 4657        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4658            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4659                local
 4660                    .language_servers_for_buffer(buffer, cx)
 4661                    .find(|(_, server)| {
 4662                        request.check_capabilities(server.adapter_server_capabilities())
 4663                    })
 4664                    .map(|(_, server)| server.clone())
 4665            }),
 4666            LanguageServerToQuery::Other(id) => self
 4667                .language_server_for_local_buffer(buffer, id, cx)
 4668                .and_then(|(_, server)| {
 4669                    request
 4670                        .check_capabilities(server.adapter_server_capabilities())
 4671                        .then(|| Arc::clone(server))
 4672                }),
 4673        }) else {
 4674            return Task::ready(Ok(Default::default()));
 4675        };
 4676
 4677        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4678
 4679        let Some(file) = file else {
 4680            return Task::ready(Ok(Default::default()));
 4681        };
 4682
 4683        let lsp_params = match request.to_lsp_params_or_response(
 4684            &file.abs_path(cx),
 4685            buffer.read(cx),
 4686            &language_server,
 4687            cx,
 4688        ) {
 4689            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4690            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4691            Err(err) => {
 4692                let message = format!(
 4693                    "{} via {} failed: {}",
 4694                    request.display_name(),
 4695                    language_server.name(),
 4696                    err
 4697                );
 4698                // rust-analyzer likes to error with this when its still loading up
 4699                if !message.ends_with("content modified") {
 4700                    log::warn!("{message}");
 4701                }
 4702                return Task::ready(Err(anyhow!(message)));
 4703            }
 4704        };
 4705
 4706        let status = request.status();
 4707        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4708            return Task::ready(Ok(Default::default()));
 4709        }
 4710        cx.spawn(async move |this, cx| {
 4711            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4712
 4713            let id = lsp_request.id();
 4714            let _cleanup = if status.is_some() {
 4715                cx.update(|cx| {
 4716                    this.update(cx, |this, cx| {
 4717                        this.on_lsp_work_start(
 4718                            language_server.server_id(),
 4719                            ProgressToken::Number(id),
 4720                            LanguageServerProgress {
 4721                                is_disk_based_diagnostics_progress: false,
 4722                                is_cancellable: false,
 4723                                title: None,
 4724                                message: status.clone(),
 4725                                percentage: None,
 4726                                last_update_at: cx.background_executor().now(),
 4727                            },
 4728                            cx,
 4729                        );
 4730                    })
 4731                })
 4732                .log_err();
 4733
 4734                Some(defer(|| {
 4735                    cx.update(|cx| {
 4736                        this.update(cx, |this, cx| {
 4737                            this.on_lsp_work_end(
 4738                                language_server.server_id(),
 4739                                ProgressToken::Number(id),
 4740                                cx,
 4741                            );
 4742                        })
 4743                    })
 4744                    .log_err();
 4745                }))
 4746            } else {
 4747                None
 4748            };
 4749
 4750            let result = lsp_request.await.into_response();
 4751
 4752            let response = result.map_err(|err| {
 4753                let message = format!(
 4754                    "{} via {} failed: {}",
 4755                    request.display_name(),
 4756                    language_server.name(),
 4757                    err
 4758                );
 4759                // rust-analyzer likes to error with this when its still loading up
 4760                if !message.ends_with("content modified") {
 4761                    log::warn!("{message}");
 4762                }
 4763                anyhow::anyhow!(message)
 4764            })?;
 4765
 4766            request
 4767                .response_from_lsp(
 4768                    response,
 4769                    this.upgrade().context("no app context")?,
 4770                    buffer,
 4771                    language_server.server_id(),
 4772                    cx.clone(),
 4773                )
 4774                .await
 4775        })
 4776    }
 4777
 4778    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4779        let mut language_formatters_to_check = Vec::new();
 4780        for buffer in self.buffer_store.read(cx).buffers() {
 4781            let buffer = buffer.read(cx);
 4782            let buffer_file = File::from_dyn(buffer.file());
 4783            let buffer_language = buffer.language();
 4784            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4785            if buffer_language.is_some() {
 4786                language_formatters_to_check.push((
 4787                    buffer_file.map(|f| f.worktree_id(cx)),
 4788                    settings.into_owned(),
 4789                ));
 4790            }
 4791        }
 4792
 4793        self.request_workspace_config_refresh();
 4794
 4795        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4796            prettier_store.update(cx, |prettier_store, cx| {
 4797                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4798            })
 4799        }
 4800
 4801        cx.notify();
 4802    }
 4803
 4804    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4805        let buffer_store = self.buffer_store.clone();
 4806        let Some(local) = self.as_local_mut() else {
 4807            return;
 4808        };
 4809        let mut adapters = BTreeMap::default();
 4810        let get_adapter = {
 4811            let languages = local.languages.clone();
 4812            let environment = local.environment.clone();
 4813            let weak = local.weak.clone();
 4814            let worktree_store = local.worktree_store.clone();
 4815            let http_client = local.http_client.clone();
 4816            let fs = local.fs.clone();
 4817            move |worktree_id, cx: &mut App| {
 4818                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4819                Some(LocalLspAdapterDelegate::new(
 4820                    languages.clone(),
 4821                    &environment,
 4822                    weak.clone(),
 4823                    &worktree,
 4824                    http_client.clone(),
 4825                    fs.clone(),
 4826                    cx,
 4827                ))
 4828            }
 4829        };
 4830
 4831        let mut messages_to_report = Vec::new();
 4832        let (new_tree, to_stop) = {
 4833            let mut rebase = local.lsp_tree.rebase();
 4834            let buffers = buffer_store
 4835                .read(cx)
 4836                .buffers()
 4837                .filter_map(|buffer| {
 4838                    let raw_buffer = buffer.read(cx);
 4839                    if !local
 4840                        .registered_buffers
 4841                        .contains_key(&raw_buffer.remote_id())
 4842                    {
 4843                        return None;
 4844                    }
 4845                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4846                    let language = raw_buffer.language().cloned()?;
 4847                    Some((file, language, raw_buffer.remote_id()))
 4848                })
 4849                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4850            for (file, language, buffer_id) in buffers {
 4851                let worktree_id = file.worktree_id(cx);
 4852                let Some(worktree) = local
 4853                    .worktree_store
 4854                    .read(cx)
 4855                    .worktree_for_id(worktree_id, cx)
 4856                else {
 4857                    continue;
 4858                };
 4859
 4860                if let Some((_, apply)) = local.reuse_existing_language_server(
 4861                    rebase.server_tree(),
 4862                    &worktree,
 4863                    &language.name(),
 4864                    cx,
 4865                ) {
 4866                    (apply)(rebase.server_tree());
 4867                } else if let Some(lsp_delegate) = adapters
 4868                    .entry(worktree_id)
 4869                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4870                    .clone()
 4871                {
 4872                    let delegate =
 4873                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4874                    let path = file
 4875                        .path()
 4876                        .parent()
 4877                        .map(Arc::from)
 4878                        .unwrap_or_else(|| file.path().clone());
 4879                    let worktree_path = ProjectPath { worktree_id, path };
 4880                    let abs_path = file.abs_path(cx);
 4881                    let nodes = rebase
 4882                        .walk(
 4883                            worktree_path,
 4884                            language.name(),
 4885                            language.manifest(),
 4886                            delegate.clone(),
 4887                            cx,
 4888                        )
 4889                        .collect::<Vec<_>>();
 4890                    for node in nodes {
 4891                        let server_id = node.server_id_or_init(|disposition| {
 4892                            let path = &disposition.path;
 4893                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4894                            let key = LanguageServerSeed {
 4895                                worktree_id,
 4896                                name: disposition.server_name.clone(),
 4897                                settings: disposition.settings.clone(),
 4898                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4899                                    path.worktree_id,
 4900                                    &path.path,
 4901                                    language.name(),
 4902                                ),
 4903                            };
 4904                            local.language_server_ids.remove(&key);
 4905
 4906                            let server_id = local.get_or_insert_language_server(
 4907                                &worktree,
 4908                                lsp_delegate.clone(),
 4909                                disposition,
 4910                                &language.name(),
 4911                                cx,
 4912                            );
 4913                            if let Some(state) = local.language_servers.get(&server_id)
 4914                                && let Ok(uri) = uri
 4915                            {
 4916                                state.add_workspace_folder(uri);
 4917                            };
 4918                            server_id
 4919                        });
 4920
 4921                        if let Some(language_server_id) = server_id {
 4922                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4923                                language_server_id,
 4924                                name: node.name(),
 4925                                message:
 4926                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4927                                        proto::RegisteredForBuffer {
 4928                                            buffer_abs_path: abs_path
 4929                                                .to_string_lossy()
 4930                                                .into_owned(),
 4931                                            buffer_id: buffer_id.to_proto(),
 4932                                        },
 4933                                    ),
 4934                            });
 4935                        }
 4936                    }
 4937                } else {
 4938                    continue;
 4939                }
 4940            }
 4941            rebase.finish()
 4942        };
 4943        for message in messages_to_report {
 4944            cx.emit(message);
 4945        }
 4946        local.lsp_tree = new_tree;
 4947        for (id, _) in to_stop {
 4948            self.stop_local_language_server(id, cx).detach();
 4949        }
 4950    }
 4951
 4952    pub fn apply_code_action(
 4953        &self,
 4954        buffer_handle: Entity<Buffer>,
 4955        mut action: CodeAction,
 4956        push_to_history: bool,
 4957        cx: &mut Context<Self>,
 4958    ) -> Task<Result<ProjectTransaction>> {
 4959        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4960            let request = proto::ApplyCodeAction {
 4961                project_id,
 4962                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4963                action: Some(Self::serialize_code_action(&action)),
 4964            };
 4965            let buffer_store = self.buffer_store();
 4966            cx.spawn(async move |_, cx| {
 4967                let response = upstream_client
 4968                    .request(request)
 4969                    .await?
 4970                    .transaction
 4971                    .context("missing transaction")?;
 4972
 4973                buffer_store
 4974                    .update(cx, |buffer_store, cx| {
 4975                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4976                    })?
 4977                    .await
 4978            })
 4979        } else if self.mode.is_local() {
 4980            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4981                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4982                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4983            }) else {
 4984                return Task::ready(Ok(ProjectTransaction::default()));
 4985            };
 4986            cx.spawn(async move |this,  cx| {
 4987                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4988                    .await
 4989                    .context("resolving a code action")?;
 4990                if let Some(edit) = action.lsp_action.edit()
 4991                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4992                        return LocalLspStore::deserialize_workspace_edit(
 4993                            this.upgrade().context("no app present")?,
 4994                            edit.clone(),
 4995                            push_to_history,
 4996
 4997                            lang_server.clone(),
 4998                            cx,
 4999                        )
 5000                        .await;
 5001                    }
 5002
 5003                if let Some(command) = action.lsp_action.command() {
 5004                    let server_capabilities = lang_server.capabilities();
 5005                    let available_commands = server_capabilities
 5006                        .execute_command_provider
 5007                        .as_ref()
 5008                        .map(|options| options.commands.as_slice())
 5009                        .unwrap_or_default();
 5010                    if available_commands.contains(&command.command) {
 5011                        this.update(cx, |this, _| {
 5012                            this.as_local_mut()
 5013                                .unwrap()
 5014                                .last_workspace_edits_by_language_server
 5015                                .remove(&lang_server.server_id());
 5016                        })?;
 5017
 5018                        let _result = lang_server
 5019                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5020                                command: command.command.clone(),
 5021                                arguments: command.arguments.clone().unwrap_or_default(),
 5022                                ..lsp::ExecuteCommandParams::default()
 5023                            })
 5024                            .await.into_response()
 5025                            .context("execute command")?;
 5026
 5027                        return this.update(cx, |this, _| {
 5028                            this.as_local_mut()
 5029                                .unwrap()
 5030                                .last_workspace_edits_by_language_server
 5031                                .remove(&lang_server.server_id())
 5032                                .unwrap_or_default()
 5033                        });
 5034                    } else {
 5035                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5036                    }
 5037                }
 5038
 5039                Ok(ProjectTransaction::default())
 5040            })
 5041        } else {
 5042            Task::ready(Err(anyhow!("no upstream client and not local")))
 5043        }
 5044    }
 5045
 5046    pub fn apply_code_action_kind(
 5047        &mut self,
 5048        buffers: HashSet<Entity<Buffer>>,
 5049        kind: CodeActionKind,
 5050        push_to_history: bool,
 5051        cx: &mut Context<Self>,
 5052    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5053        if self.as_local().is_some() {
 5054            cx.spawn(async move |lsp_store, cx| {
 5055                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5056                let result = LocalLspStore::execute_code_action_kind_locally(
 5057                    lsp_store.clone(),
 5058                    buffers,
 5059                    kind,
 5060                    push_to_history,
 5061                    cx,
 5062                )
 5063                .await;
 5064                lsp_store.update(cx, |lsp_store, _| {
 5065                    lsp_store.update_last_formatting_failure(&result);
 5066                })?;
 5067                result
 5068            })
 5069        } else if let Some((client, project_id)) = self.upstream_client() {
 5070            let buffer_store = self.buffer_store();
 5071            cx.spawn(async move |lsp_store, cx| {
 5072                let result = client
 5073                    .request(proto::ApplyCodeActionKind {
 5074                        project_id,
 5075                        kind: kind.as_str().to_owned(),
 5076                        buffer_ids: buffers
 5077                            .iter()
 5078                            .map(|buffer| {
 5079                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5080                            })
 5081                            .collect::<Result<_>>()?,
 5082                    })
 5083                    .await
 5084                    .and_then(|result| result.transaction.context("missing transaction"));
 5085                lsp_store.update(cx, |lsp_store, _| {
 5086                    lsp_store.update_last_formatting_failure(&result);
 5087                })?;
 5088
 5089                let transaction_response = result?;
 5090                buffer_store
 5091                    .update(cx, |buffer_store, cx| {
 5092                        buffer_store.deserialize_project_transaction(
 5093                            transaction_response,
 5094                            push_to_history,
 5095                            cx,
 5096                        )
 5097                    })?
 5098                    .await
 5099            })
 5100        } else {
 5101            Task::ready(Ok(ProjectTransaction::default()))
 5102        }
 5103    }
 5104
 5105    pub fn resolved_hint(
 5106        &mut self,
 5107        buffer_id: BufferId,
 5108        id: InlayId,
 5109        cx: &mut Context<Self>,
 5110    ) -> Option<ResolvedHint> {
 5111        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5112
 5113        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5114        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5115        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5116        let (server_id, resolve_data) = match &hint.resolve_state {
 5117            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5118            ResolveState::Resolving => {
 5119                return Some(ResolvedHint::Resolving(
 5120                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5121                ));
 5122            }
 5123            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5124        };
 5125
 5126        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5127        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5128        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5129            id,
 5130            cx.spawn(async move |lsp_store, cx| {
 5131                let resolved_hint = resolve_task.await;
 5132                lsp_store
 5133                    .update(cx, |lsp_store, _| {
 5134                        if let Some(old_inlay_hint) = lsp_store
 5135                            .lsp_data
 5136                            .get_mut(&buffer_id)
 5137                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5138                        {
 5139                            match resolved_hint {
 5140                                Ok(resolved_hint) => {
 5141                                    *old_inlay_hint = resolved_hint;
 5142                                }
 5143                                Err(e) => {
 5144                                    old_inlay_hint.resolve_state =
 5145                                        ResolveState::CanResolve(server_id, resolve_data);
 5146                                    log::error!("Inlay hint resolve failed: {e:#}");
 5147                                }
 5148                            }
 5149                        }
 5150                    })
 5151                    .ok();
 5152            })
 5153            .shared(),
 5154        );
 5155        debug_assert!(
 5156            previous_task.is_none(),
 5157            "Did not change hint's resolve state after spawning its resolve"
 5158        );
 5159        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5160        None
 5161    }
 5162
 5163    fn resolve_inlay_hint(
 5164        &self,
 5165        mut hint: InlayHint,
 5166        buffer: Entity<Buffer>,
 5167        server_id: LanguageServerId,
 5168        cx: &mut Context<Self>,
 5169    ) -> Task<anyhow::Result<InlayHint>> {
 5170        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5171            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5172            {
 5173                hint.resolve_state = ResolveState::Resolved;
 5174                return Task::ready(Ok(hint));
 5175            }
 5176            let request = proto::ResolveInlayHint {
 5177                project_id,
 5178                buffer_id: buffer.read(cx).remote_id().into(),
 5179                language_server_id: server_id.0 as u64,
 5180                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5181            };
 5182            cx.background_spawn(async move {
 5183                let response = upstream_client
 5184                    .request(request)
 5185                    .await
 5186                    .context("inlay hints proto request")?;
 5187                match response.hint {
 5188                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5189                        .context("inlay hints proto resolve response conversion"),
 5190                    None => Ok(hint),
 5191                }
 5192            })
 5193        } else {
 5194            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5195                self.language_server_for_local_buffer(buffer, server_id, cx)
 5196                    .map(|(_, server)| server.clone())
 5197            }) else {
 5198                return Task::ready(Ok(hint));
 5199            };
 5200            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5201                return Task::ready(Ok(hint));
 5202            }
 5203            let buffer_snapshot = buffer.read(cx).snapshot();
 5204            cx.spawn(async move |_, cx| {
 5205                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5206                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5207                );
 5208                let resolved_hint = resolve_task
 5209                    .await
 5210                    .into_response()
 5211                    .context("inlay hint resolve LSP request")?;
 5212                let resolved_hint = InlayHints::lsp_to_project_hint(
 5213                    resolved_hint,
 5214                    &buffer,
 5215                    server_id,
 5216                    ResolveState::Resolved,
 5217                    false,
 5218                    cx,
 5219                )
 5220                .await?;
 5221                Ok(resolved_hint)
 5222            })
 5223        }
 5224    }
 5225
 5226    pub fn resolve_color_presentation(
 5227        &mut self,
 5228        mut color: DocumentColor,
 5229        buffer: Entity<Buffer>,
 5230        server_id: LanguageServerId,
 5231        cx: &mut Context<Self>,
 5232    ) -> Task<Result<DocumentColor>> {
 5233        if color.resolved {
 5234            return Task::ready(Ok(color));
 5235        }
 5236
 5237        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5238            let start = color.lsp_range.start;
 5239            let end = color.lsp_range.end;
 5240            let request = proto::GetColorPresentation {
 5241                project_id,
 5242                server_id: server_id.to_proto(),
 5243                buffer_id: buffer.read(cx).remote_id().into(),
 5244                color: Some(proto::ColorInformation {
 5245                    red: color.color.red,
 5246                    green: color.color.green,
 5247                    blue: color.color.blue,
 5248                    alpha: color.color.alpha,
 5249                    lsp_range_start: Some(proto::PointUtf16 {
 5250                        row: start.line,
 5251                        column: start.character,
 5252                    }),
 5253                    lsp_range_end: Some(proto::PointUtf16 {
 5254                        row: end.line,
 5255                        column: end.character,
 5256                    }),
 5257                }),
 5258            };
 5259            cx.background_spawn(async move {
 5260                let response = upstream_client
 5261                    .request(request)
 5262                    .await
 5263                    .context("color presentation proto request")?;
 5264                color.resolved = true;
 5265                color.color_presentations = response
 5266                    .presentations
 5267                    .into_iter()
 5268                    .map(|presentation| ColorPresentation {
 5269                        label: SharedString::from(presentation.label),
 5270                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5271                        additional_text_edits: presentation
 5272                            .additional_text_edits
 5273                            .into_iter()
 5274                            .filter_map(deserialize_lsp_edit)
 5275                            .collect(),
 5276                    })
 5277                    .collect();
 5278                Ok(color)
 5279            })
 5280        } else {
 5281            let path = match buffer
 5282                .update(cx, |buffer, cx| {
 5283                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5284                })
 5285                .context("buffer with the missing path")
 5286            {
 5287                Ok(path) => path,
 5288                Err(e) => return Task::ready(Err(e)),
 5289            };
 5290            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5291                self.language_server_for_local_buffer(buffer, server_id, cx)
 5292                    .map(|(_, server)| server.clone())
 5293            }) else {
 5294                return Task::ready(Ok(color));
 5295            };
 5296            cx.background_spawn(async move {
 5297                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5298                    lsp::ColorPresentationParams {
 5299                        text_document: make_text_document_identifier(&path)?,
 5300                        color: color.color,
 5301                        range: color.lsp_range,
 5302                        work_done_progress_params: Default::default(),
 5303                        partial_result_params: Default::default(),
 5304                    },
 5305                );
 5306                color.color_presentations = resolve_task
 5307                    .await
 5308                    .into_response()
 5309                    .context("color presentation resolve LSP request")?
 5310                    .into_iter()
 5311                    .map(|presentation| ColorPresentation {
 5312                        label: SharedString::from(presentation.label),
 5313                        text_edit: presentation.text_edit,
 5314                        additional_text_edits: presentation
 5315                            .additional_text_edits
 5316                            .unwrap_or_default(),
 5317                    })
 5318                    .collect();
 5319                color.resolved = true;
 5320                Ok(color)
 5321            })
 5322        }
 5323    }
 5324
 5325    pub(crate) fn linked_edits(
 5326        &mut self,
 5327        buffer: &Entity<Buffer>,
 5328        position: Anchor,
 5329        cx: &mut Context<Self>,
 5330    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5331        let snapshot = buffer.read(cx).snapshot();
 5332        let scope = snapshot.language_scope_at(position);
 5333        let Some(server_id) = self
 5334            .as_local()
 5335            .and_then(|local| {
 5336                buffer.update(cx, |buffer, cx| {
 5337                    local
 5338                        .language_servers_for_buffer(buffer, cx)
 5339                        .filter(|(_, server)| {
 5340                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5341                        })
 5342                        .filter(|(adapter, _)| {
 5343                            scope
 5344                                .as_ref()
 5345                                .map(|scope| scope.language_allowed(&adapter.name))
 5346                                .unwrap_or(true)
 5347                        })
 5348                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5349                        .next()
 5350                })
 5351            })
 5352            .or_else(|| {
 5353                self.upstream_client()
 5354                    .is_some()
 5355                    .then_some(LanguageServerToQuery::FirstCapable)
 5356            })
 5357            .filter(|_| {
 5358                maybe!({
 5359                    let language = buffer.read(cx).language_at(position)?;
 5360                    Some(
 5361                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5362                            .linked_edits,
 5363                    )
 5364                }) == Some(true)
 5365            })
 5366        else {
 5367            return Task::ready(Ok(Vec::new()));
 5368        };
 5369
 5370        self.request_lsp(
 5371            buffer.clone(),
 5372            server_id,
 5373            LinkedEditingRange { position },
 5374            cx,
 5375        )
 5376    }
 5377
 5378    fn apply_on_type_formatting(
 5379        &mut self,
 5380        buffer: Entity<Buffer>,
 5381        position: Anchor,
 5382        trigger: String,
 5383        cx: &mut Context<Self>,
 5384    ) -> Task<Result<Option<Transaction>>> {
 5385        if let Some((client, project_id)) = self.upstream_client() {
 5386            if !self.check_if_capable_for_proto_request(
 5387                &buffer,
 5388                |capabilities| {
 5389                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5390                },
 5391                cx,
 5392            ) {
 5393                return Task::ready(Ok(None));
 5394            }
 5395            let request = proto::OnTypeFormatting {
 5396                project_id,
 5397                buffer_id: buffer.read(cx).remote_id().into(),
 5398                position: Some(serialize_anchor(&position)),
 5399                trigger,
 5400                version: serialize_version(&buffer.read(cx).version()),
 5401            };
 5402            cx.background_spawn(async move {
 5403                client
 5404                    .request(request)
 5405                    .await?
 5406                    .transaction
 5407                    .map(language::proto::deserialize_transaction)
 5408                    .transpose()
 5409            })
 5410        } else if let Some(local) = self.as_local_mut() {
 5411            let buffer_id = buffer.read(cx).remote_id();
 5412            local.buffers_being_formatted.insert(buffer_id);
 5413            cx.spawn(async move |this, cx| {
 5414                let _cleanup = defer({
 5415                    let this = this.clone();
 5416                    let mut cx = cx.clone();
 5417                    move || {
 5418                        this.update(&mut cx, |this, _| {
 5419                            if let Some(local) = this.as_local_mut() {
 5420                                local.buffers_being_formatted.remove(&buffer_id);
 5421                            }
 5422                        })
 5423                        .ok();
 5424                    }
 5425                });
 5426
 5427                buffer
 5428                    .update(cx, |buffer, _| {
 5429                        buffer.wait_for_edits(Some(position.timestamp))
 5430                    })?
 5431                    .await?;
 5432                this.update(cx, |this, cx| {
 5433                    let position = position.to_point_utf16(buffer.read(cx));
 5434                    this.on_type_format(buffer, position, trigger, false, cx)
 5435                })?
 5436                .await
 5437            })
 5438        } else {
 5439            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5440        }
 5441    }
 5442
 5443    pub fn on_type_format<T: ToPointUtf16>(
 5444        &mut self,
 5445        buffer: Entity<Buffer>,
 5446        position: T,
 5447        trigger: String,
 5448        push_to_history: bool,
 5449        cx: &mut Context<Self>,
 5450    ) -> Task<Result<Option<Transaction>>> {
 5451        let position = position.to_point_utf16(buffer.read(cx));
 5452        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5453    }
 5454
 5455    fn on_type_format_impl(
 5456        &mut self,
 5457        buffer: Entity<Buffer>,
 5458        position: PointUtf16,
 5459        trigger: String,
 5460        push_to_history: bool,
 5461        cx: &mut Context<Self>,
 5462    ) -> Task<Result<Option<Transaction>>> {
 5463        let options = buffer.update(cx, |buffer, cx| {
 5464            lsp_command::lsp_formatting_options(
 5465                language_settings(
 5466                    buffer.language_at(position).map(|l| l.name()),
 5467                    buffer.file(),
 5468                    cx,
 5469                )
 5470                .as_ref(),
 5471            )
 5472        });
 5473
 5474        cx.spawn(async move |this, cx| {
 5475            if let Some(waiter) =
 5476                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5477            {
 5478                waiter.await?;
 5479            }
 5480            cx.update(|cx| {
 5481                this.update(cx, |this, cx| {
 5482                    this.request_lsp(
 5483                        buffer.clone(),
 5484                        LanguageServerToQuery::FirstCapable,
 5485                        OnTypeFormatting {
 5486                            position,
 5487                            trigger,
 5488                            options,
 5489                            push_to_history,
 5490                        },
 5491                        cx,
 5492                    )
 5493                })
 5494            })??
 5495            .await
 5496        })
 5497    }
 5498
 5499    pub fn definitions(
 5500        &mut self,
 5501        buffer: &Entity<Buffer>,
 5502        position: PointUtf16,
 5503        cx: &mut Context<Self>,
 5504    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5505        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5506            let request = GetDefinitions { position };
 5507            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5508                return Task::ready(Ok(None));
 5509            }
 5510            let request_task = upstream_client.request_lsp(
 5511                project_id,
 5512                None,
 5513                LSP_REQUEST_TIMEOUT,
 5514                cx.background_executor().clone(),
 5515                request.to_proto(project_id, buffer.read(cx)),
 5516            );
 5517            let buffer = buffer.clone();
 5518            cx.spawn(async move |weak_lsp_store, cx| {
 5519                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5520                    return Ok(None);
 5521                };
 5522                let Some(responses) = request_task.await? else {
 5523                    return Ok(None);
 5524                };
 5525                let actions = join_all(responses.payload.into_iter().map(|response| {
 5526                    GetDefinitions { position }.response_from_proto(
 5527                        response.response,
 5528                        lsp_store.clone(),
 5529                        buffer.clone(),
 5530                        cx.clone(),
 5531                    )
 5532                }))
 5533                .await;
 5534
 5535                Ok(Some(
 5536                    actions
 5537                        .into_iter()
 5538                        .collect::<Result<Vec<Vec<_>>>>()?
 5539                        .into_iter()
 5540                        .flatten()
 5541                        .dedup()
 5542                        .collect(),
 5543                ))
 5544            })
 5545        } else {
 5546            let definitions_task = self.request_multiple_lsp_locally(
 5547                buffer,
 5548                Some(position),
 5549                GetDefinitions { position },
 5550                cx,
 5551            );
 5552            cx.background_spawn(async move {
 5553                Ok(Some(
 5554                    definitions_task
 5555                        .await
 5556                        .into_iter()
 5557                        .flat_map(|(_, definitions)| definitions)
 5558                        .dedup()
 5559                        .collect(),
 5560                ))
 5561            })
 5562        }
 5563    }
 5564
 5565    pub fn declarations(
 5566        &mut self,
 5567        buffer: &Entity<Buffer>,
 5568        position: PointUtf16,
 5569        cx: &mut Context<Self>,
 5570    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5571        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5572            let request = GetDeclarations { position };
 5573            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5574                return Task::ready(Ok(None));
 5575            }
 5576            let request_task = upstream_client.request_lsp(
 5577                project_id,
 5578                None,
 5579                LSP_REQUEST_TIMEOUT,
 5580                cx.background_executor().clone(),
 5581                request.to_proto(project_id, buffer.read(cx)),
 5582            );
 5583            let buffer = buffer.clone();
 5584            cx.spawn(async move |weak_lsp_store, cx| {
 5585                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5586                    return Ok(None);
 5587                };
 5588                let Some(responses) = request_task.await? else {
 5589                    return Ok(None);
 5590                };
 5591                let actions = join_all(responses.payload.into_iter().map(|response| {
 5592                    GetDeclarations { position }.response_from_proto(
 5593                        response.response,
 5594                        lsp_store.clone(),
 5595                        buffer.clone(),
 5596                        cx.clone(),
 5597                    )
 5598                }))
 5599                .await;
 5600
 5601                Ok(Some(
 5602                    actions
 5603                        .into_iter()
 5604                        .collect::<Result<Vec<Vec<_>>>>()?
 5605                        .into_iter()
 5606                        .flatten()
 5607                        .dedup()
 5608                        .collect(),
 5609                ))
 5610            })
 5611        } else {
 5612            let declarations_task = self.request_multiple_lsp_locally(
 5613                buffer,
 5614                Some(position),
 5615                GetDeclarations { position },
 5616                cx,
 5617            );
 5618            cx.background_spawn(async move {
 5619                Ok(Some(
 5620                    declarations_task
 5621                        .await
 5622                        .into_iter()
 5623                        .flat_map(|(_, declarations)| declarations)
 5624                        .dedup()
 5625                        .collect(),
 5626                ))
 5627            })
 5628        }
 5629    }
 5630
 5631    pub fn type_definitions(
 5632        &mut self,
 5633        buffer: &Entity<Buffer>,
 5634        position: PointUtf16,
 5635        cx: &mut Context<Self>,
 5636    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5637        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5638            let request = GetTypeDefinitions { position };
 5639            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5640                return Task::ready(Ok(None));
 5641            }
 5642            let request_task = upstream_client.request_lsp(
 5643                project_id,
 5644                None,
 5645                LSP_REQUEST_TIMEOUT,
 5646                cx.background_executor().clone(),
 5647                request.to_proto(project_id, buffer.read(cx)),
 5648            );
 5649            let buffer = buffer.clone();
 5650            cx.spawn(async move |weak_lsp_store, cx| {
 5651                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5652                    return Ok(None);
 5653                };
 5654                let Some(responses) = request_task.await? else {
 5655                    return Ok(None);
 5656                };
 5657                let actions = join_all(responses.payload.into_iter().map(|response| {
 5658                    GetTypeDefinitions { position }.response_from_proto(
 5659                        response.response,
 5660                        lsp_store.clone(),
 5661                        buffer.clone(),
 5662                        cx.clone(),
 5663                    )
 5664                }))
 5665                .await;
 5666
 5667                Ok(Some(
 5668                    actions
 5669                        .into_iter()
 5670                        .collect::<Result<Vec<Vec<_>>>>()?
 5671                        .into_iter()
 5672                        .flatten()
 5673                        .dedup()
 5674                        .collect(),
 5675                ))
 5676            })
 5677        } else {
 5678            let type_definitions_task = self.request_multiple_lsp_locally(
 5679                buffer,
 5680                Some(position),
 5681                GetTypeDefinitions { position },
 5682                cx,
 5683            );
 5684            cx.background_spawn(async move {
 5685                Ok(Some(
 5686                    type_definitions_task
 5687                        .await
 5688                        .into_iter()
 5689                        .flat_map(|(_, type_definitions)| type_definitions)
 5690                        .dedup()
 5691                        .collect(),
 5692                ))
 5693            })
 5694        }
 5695    }
 5696
 5697    pub fn implementations(
 5698        &mut self,
 5699        buffer: &Entity<Buffer>,
 5700        position: PointUtf16,
 5701        cx: &mut Context<Self>,
 5702    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5703        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5704            let request = GetImplementations { position };
 5705            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5706                return Task::ready(Ok(None));
 5707            }
 5708            let request_task = upstream_client.request_lsp(
 5709                project_id,
 5710                None,
 5711                LSP_REQUEST_TIMEOUT,
 5712                cx.background_executor().clone(),
 5713                request.to_proto(project_id, buffer.read(cx)),
 5714            );
 5715            let buffer = buffer.clone();
 5716            cx.spawn(async move |weak_lsp_store, cx| {
 5717                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5718                    return Ok(None);
 5719                };
 5720                let Some(responses) = request_task.await? else {
 5721                    return Ok(None);
 5722                };
 5723                let actions = join_all(responses.payload.into_iter().map(|response| {
 5724                    GetImplementations { position }.response_from_proto(
 5725                        response.response,
 5726                        lsp_store.clone(),
 5727                        buffer.clone(),
 5728                        cx.clone(),
 5729                    )
 5730                }))
 5731                .await;
 5732
 5733                Ok(Some(
 5734                    actions
 5735                        .into_iter()
 5736                        .collect::<Result<Vec<Vec<_>>>>()?
 5737                        .into_iter()
 5738                        .flatten()
 5739                        .dedup()
 5740                        .collect(),
 5741                ))
 5742            })
 5743        } else {
 5744            let implementations_task = self.request_multiple_lsp_locally(
 5745                buffer,
 5746                Some(position),
 5747                GetImplementations { position },
 5748                cx,
 5749            );
 5750            cx.background_spawn(async move {
 5751                Ok(Some(
 5752                    implementations_task
 5753                        .await
 5754                        .into_iter()
 5755                        .flat_map(|(_, implementations)| implementations)
 5756                        .dedup()
 5757                        .collect(),
 5758                ))
 5759            })
 5760        }
 5761    }
 5762
 5763    pub fn references(
 5764        &mut self,
 5765        buffer: &Entity<Buffer>,
 5766        position: PointUtf16,
 5767        cx: &mut Context<Self>,
 5768    ) -> Task<Result<Option<Vec<Location>>>> {
 5769        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5770            let request = GetReferences { position };
 5771            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5772                return Task::ready(Ok(None));
 5773            }
 5774
 5775            let request_task = upstream_client.request_lsp(
 5776                project_id,
 5777                None,
 5778                LSP_REQUEST_TIMEOUT,
 5779                cx.background_executor().clone(),
 5780                request.to_proto(project_id, buffer.read(cx)),
 5781            );
 5782            let buffer = buffer.clone();
 5783            cx.spawn(async move |weak_lsp_store, cx| {
 5784                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5785                    return Ok(None);
 5786                };
 5787                let Some(responses) = request_task.await? else {
 5788                    return Ok(None);
 5789                };
 5790
 5791                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5792                    GetReferences { position }.response_from_proto(
 5793                        lsp_response.response,
 5794                        lsp_store.clone(),
 5795                        buffer.clone(),
 5796                        cx.clone(),
 5797                    )
 5798                }))
 5799                .await
 5800                .into_iter()
 5801                .collect::<Result<Vec<Vec<_>>>>()?
 5802                .into_iter()
 5803                .flatten()
 5804                .dedup()
 5805                .collect();
 5806                Ok(Some(locations))
 5807            })
 5808        } else {
 5809            let references_task = self.request_multiple_lsp_locally(
 5810                buffer,
 5811                Some(position),
 5812                GetReferences { position },
 5813                cx,
 5814            );
 5815            cx.background_spawn(async move {
 5816                Ok(Some(
 5817                    references_task
 5818                        .await
 5819                        .into_iter()
 5820                        .flat_map(|(_, references)| references)
 5821                        .dedup()
 5822                        .collect(),
 5823                ))
 5824            })
 5825        }
 5826    }
 5827
 5828    pub fn code_actions(
 5829        &mut self,
 5830        buffer: &Entity<Buffer>,
 5831        range: Range<Anchor>,
 5832        kinds: Option<Vec<CodeActionKind>>,
 5833        cx: &mut Context<Self>,
 5834    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5835        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5836            let request = GetCodeActions {
 5837                range: range.clone(),
 5838                kinds: kinds.clone(),
 5839            };
 5840            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5841                return Task::ready(Ok(None));
 5842            }
 5843            let request_task = upstream_client.request_lsp(
 5844                project_id,
 5845                None,
 5846                LSP_REQUEST_TIMEOUT,
 5847                cx.background_executor().clone(),
 5848                request.to_proto(project_id, buffer.read(cx)),
 5849            );
 5850            let buffer = buffer.clone();
 5851            cx.spawn(async move |weak_lsp_store, cx| {
 5852                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5853                    return Ok(None);
 5854                };
 5855                let Some(responses) = request_task.await? else {
 5856                    return Ok(None);
 5857                };
 5858                let actions = join_all(responses.payload.into_iter().map(|response| {
 5859                    GetCodeActions {
 5860                        range: range.clone(),
 5861                        kinds: kinds.clone(),
 5862                    }
 5863                    .response_from_proto(
 5864                        response.response,
 5865                        lsp_store.clone(),
 5866                        buffer.clone(),
 5867                        cx.clone(),
 5868                    )
 5869                }))
 5870                .await;
 5871
 5872                Ok(Some(
 5873                    actions
 5874                        .into_iter()
 5875                        .collect::<Result<Vec<Vec<_>>>>()?
 5876                        .into_iter()
 5877                        .flatten()
 5878                        .collect(),
 5879                ))
 5880            })
 5881        } else {
 5882            let all_actions_task = self.request_multiple_lsp_locally(
 5883                buffer,
 5884                Some(range.start),
 5885                GetCodeActions { range, kinds },
 5886                cx,
 5887            );
 5888            cx.background_spawn(async move {
 5889                Ok(Some(
 5890                    all_actions_task
 5891                        .await
 5892                        .into_iter()
 5893                        .flat_map(|(_, actions)| actions)
 5894                        .collect(),
 5895                ))
 5896            })
 5897        }
 5898    }
 5899
 5900    pub fn code_lens_actions(
 5901        &mut self,
 5902        buffer: &Entity<Buffer>,
 5903        cx: &mut Context<Self>,
 5904    ) -> CodeLensTask {
 5905        let version_queried_for = buffer.read(cx).version();
 5906        let buffer_id = buffer.read(cx).remote_id();
 5907        let existing_servers = self.as_local().map(|local| {
 5908            local
 5909                .buffers_opened_in_servers
 5910                .get(&buffer_id)
 5911                .cloned()
 5912                .unwrap_or_default()
 5913        });
 5914
 5915        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5916            if let Some(cached_lens) = &lsp_data.code_lens {
 5917                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5918                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5919                        existing_servers != cached_lens.lens.keys().copied().collect()
 5920                    });
 5921                    if !has_different_servers {
 5922                        return Task::ready(Ok(Some(
 5923                            cached_lens.lens.values().flatten().cloned().collect(),
 5924                        )))
 5925                        .shared();
 5926                    }
 5927                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5928                    if !version_queried_for.changed_since(updating_for) {
 5929                        return running_update.clone();
 5930                    }
 5931                }
 5932            }
 5933        }
 5934
 5935        let lens_lsp_data = self
 5936            .latest_lsp_data(buffer, cx)
 5937            .code_lens
 5938            .get_or_insert_default();
 5939        let buffer = buffer.clone();
 5940        let query_version_queried_for = version_queried_for.clone();
 5941        let new_task = cx
 5942            .spawn(async move |lsp_store, cx| {
 5943                cx.background_executor()
 5944                    .timer(Duration::from_millis(30))
 5945                    .await;
 5946                let fetched_lens = lsp_store
 5947                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5948                    .map_err(Arc::new)?
 5949                    .await
 5950                    .context("fetching code lens")
 5951                    .map_err(Arc::new);
 5952                let fetched_lens = match fetched_lens {
 5953                    Ok(fetched_lens) => fetched_lens,
 5954                    Err(e) => {
 5955                        lsp_store
 5956                            .update(cx, |lsp_store, _| {
 5957                                if let Some(lens_lsp_data) = lsp_store
 5958                                    .lsp_data
 5959                                    .get_mut(&buffer_id)
 5960                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5961                                {
 5962                                    lens_lsp_data.update = None;
 5963                                }
 5964                            })
 5965                            .ok();
 5966                        return Err(e);
 5967                    }
 5968                };
 5969
 5970                lsp_store
 5971                    .update(cx, |lsp_store, _| {
 5972                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5973                        let code_lens = lsp_data.code_lens.as_mut()?;
 5974                        if let Some(fetched_lens) = fetched_lens {
 5975                            if lsp_data.buffer_version == query_version_queried_for {
 5976                                code_lens.lens.extend(fetched_lens);
 5977                            } else if !lsp_data
 5978                                .buffer_version
 5979                                .changed_since(&query_version_queried_for)
 5980                            {
 5981                                lsp_data.buffer_version = query_version_queried_for;
 5982                                code_lens.lens = fetched_lens;
 5983                            }
 5984                        }
 5985                        code_lens.update = None;
 5986                        Some(code_lens.lens.values().flatten().cloned().collect())
 5987                    })
 5988                    .map_err(Arc::new)
 5989            })
 5990            .shared();
 5991        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5992        new_task
 5993    }
 5994
 5995    fn fetch_code_lens(
 5996        &mut self,
 5997        buffer: &Entity<Buffer>,
 5998        cx: &mut Context<Self>,
 5999    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6000        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6001            let request = GetCodeLens;
 6002            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6003                return Task::ready(Ok(None));
 6004            }
 6005            let request_task = upstream_client.request_lsp(
 6006                project_id,
 6007                None,
 6008                LSP_REQUEST_TIMEOUT,
 6009                cx.background_executor().clone(),
 6010                request.to_proto(project_id, buffer.read(cx)),
 6011            );
 6012            let buffer = buffer.clone();
 6013            cx.spawn(async move |weak_lsp_store, cx| {
 6014                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6015                    return Ok(None);
 6016                };
 6017                let Some(responses) = request_task.await? else {
 6018                    return Ok(None);
 6019                };
 6020
 6021                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6022                    let lsp_store = lsp_store.clone();
 6023                    let buffer = buffer.clone();
 6024                    let cx = cx.clone();
 6025                    async move {
 6026                        (
 6027                            LanguageServerId::from_proto(response.server_id),
 6028                            GetCodeLens
 6029                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6030                                .await,
 6031                        )
 6032                    }
 6033                }))
 6034                .await;
 6035
 6036                let mut has_errors = false;
 6037                let code_lens_actions = code_lens_actions
 6038                    .into_iter()
 6039                    .filter_map(|(server_id, code_lens)| match code_lens {
 6040                        Ok(code_lens) => Some((server_id, code_lens)),
 6041                        Err(e) => {
 6042                            has_errors = true;
 6043                            log::error!("{e:#}");
 6044                            None
 6045                        }
 6046                    })
 6047                    .collect::<HashMap<_, _>>();
 6048                anyhow::ensure!(
 6049                    !has_errors || !code_lens_actions.is_empty(),
 6050                    "Failed to fetch code lens"
 6051                );
 6052                Ok(Some(code_lens_actions))
 6053            })
 6054        } else {
 6055            let code_lens_actions_task =
 6056                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6057            cx.background_spawn(async move {
 6058                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6059            })
 6060        }
 6061    }
 6062
 6063    #[inline(never)]
 6064    pub fn completions(
 6065        &self,
 6066        buffer: &Entity<Buffer>,
 6067        position: PointUtf16,
 6068        context: CompletionContext,
 6069        cx: &mut Context<Self>,
 6070    ) -> Task<Result<Vec<CompletionResponse>>> {
 6071        let language_registry = self.languages.clone();
 6072
 6073        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6074            let snapshot = buffer.read(cx).snapshot();
 6075            let offset = position.to_offset(&snapshot);
 6076            let scope = snapshot.language_scope_at(offset);
 6077            let capable_lsps = self.all_capable_for_proto_request(
 6078                buffer,
 6079                |server_name, capabilities| {
 6080                    capabilities.completion_provider.is_some()
 6081                        && scope
 6082                            .as_ref()
 6083                            .map(|scope| scope.language_allowed(server_name))
 6084                            .unwrap_or(true)
 6085                },
 6086                cx,
 6087            );
 6088            if capable_lsps.is_empty() {
 6089                return Task::ready(Ok(Vec::new()));
 6090            }
 6091
 6092            let language = buffer.read(cx).language().cloned();
 6093
 6094            // In the future, we should provide project guests with the names of LSP adapters,
 6095            // so that they can use the correct LSP adapter when computing labels. For now,
 6096            // guests just use the first LSP adapter associated with the buffer's language.
 6097            let lsp_adapter = language.as_ref().and_then(|language| {
 6098                language_registry
 6099                    .lsp_adapters(&language.name())
 6100                    .first()
 6101                    .cloned()
 6102            });
 6103
 6104            let buffer = buffer.clone();
 6105
 6106            cx.spawn(async move |this, cx| {
 6107                let requests = join_all(
 6108                    capable_lsps
 6109                        .into_iter()
 6110                        .map(|id| {
 6111                            let request = GetCompletions {
 6112                                position,
 6113                                context: context.clone(),
 6114                                server_id: Some(id),
 6115                            };
 6116                            let buffer = buffer.clone();
 6117                            let language = language.clone();
 6118                            let lsp_adapter = lsp_adapter.clone();
 6119                            let upstream_client = upstream_client.clone();
 6120                            let response = this
 6121                                .update(cx, |this, cx| {
 6122                                    this.send_lsp_proto_request(
 6123                                        buffer,
 6124                                        upstream_client,
 6125                                        project_id,
 6126                                        request,
 6127                                        cx,
 6128                                    )
 6129                                })
 6130                                .log_err();
 6131                            async move {
 6132                                let response = response?.await.log_err()?;
 6133
 6134                                let completions = populate_labels_for_completions(
 6135                                    response.completions,
 6136                                    language,
 6137                                    lsp_adapter,
 6138                                )
 6139                                .await;
 6140
 6141                                Some(CompletionResponse {
 6142                                    completions,
 6143                                    display_options: CompletionDisplayOptions::default(),
 6144                                    is_incomplete: response.is_incomplete,
 6145                                })
 6146                            }
 6147                        })
 6148                        .collect::<Vec<_>>(),
 6149                );
 6150                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6151            })
 6152        } else if let Some(local) = self.as_local() {
 6153            let snapshot = buffer.read(cx).snapshot();
 6154            let offset = position.to_offset(&snapshot);
 6155            let scope = snapshot.language_scope_at(offset);
 6156            let language = snapshot.language().cloned();
 6157            let completion_settings = language_settings(
 6158                language.as_ref().map(|language| language.name()),
 6159                buffer.read(cx).file(),
 6160                cx,
 6161            )
 6162            .completions
 6163            .clone();
 6164            if !completion_settings.lsp {
 6165                return Task::ready(Ok(Vec::new()));
 6166            }
 6167
 6168            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6169                local
 6170                    .language_servers_for_buffer(buffer, cx)
 6171                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6172                    .filter(|(adapter, _)| {
 6173                        scope
 6174                            .as_ref()
 6175                            .map(|scope| scope.language_allowed(&adapter.name))
 6176                            .unwrap_or(true)
 6177                    })
 6178                    .map(|(_, server)| server.server_id())
 6179                    .collect()
 6180            });
 6181
 6182            let buffer = buffer.clone();
 6183            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6184            let lsp_timeout = if lsp_timeout > 0 {
 6185                Some(Duration::from_millis(lsp_timeout))
 6186            } else {
 6187                None
 6188            };
 6189            cx.spawn(async move |this,  cx| {
 6190                let mut tasks = Vec::with_capacity(server_ids.len());
 6191                this.update(cx, |lsp_store, cx| {
 6192                    for server_id in server_ids {
 6193                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6194                        let lsp_timeout = lsp_timeout
 6195                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6196                        let mut timeout = cx.background_spawn(async move {
 6197                            match lsp_timeout {
 6198                                Some(lsp_timeout) => {
 6199                                    lsp_timeout.await;
 6200                                    true
 6201                                },
 6202                                None => false,
 6203                            }
 6204                        }).fuse();
 6205                        let mut lsp_request = lsp_store.request_lsp(
 6206                            buffer.clone(),
 6207                            LanguageServerToQuery::Other(server_id),
 6208                            GetCompletions {
 6209                                position,
 6210                                context: context.clone(),
 6211                                server_id: Some(server_id),
 6212                            },
 6213                            cx,
 6214                        ).fuse();
 6215                        let new_task = cx.background_spawn(async move {
 6216                            select_biased! {
 6217                                response = lsp_request => anyhow::Ok(Some(response?)),
 6218                                timeout_happened = timeout => {
 6219                                    if timeout_happened {
 6220                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6221                                        Ok(None)
 6222                                    } else {
 6223                                        let completions = lsp_request.await?;
 6224                                        Ok(Some(completions))
 6225                                    }
 6226                                },
 6227                            }
 6228                        });
 6229                        tasks.push((lsp_adapter, new_task));
 6230                    }
 6231                })?;
 6232
 6233                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6234                    let completion_response = task.await.ok()??;
 6235                    let completions = populate_labels_for_completions(
 6236                            completion_response.completions,
 6237                            language.clone(),
 6238                            lsp_adapter,
 6239                        )
 6240                        .await;
 6241                    Some(CompletionResponse {
 6242                        completions,
 6243                        display_options: CompletionDisplayOptions::default(),
 6244                        is_incomplete: completion_response.is_incomplete,
 6245                    })
 6246                });
 6247
 6248                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6249
 6250                Ok(responses.into_iter().flatten().collect())
 6251            })
 6252        } else {
 6253            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6254        }
 6255    }
 6256
 6257    pub fn resolve_completions(
 6258        &self,
 6259        buffer: Entity<Buffer>,
 6260        completion_indices: Vec<usize>,
 6261        completions: Rc<RefCell<Box<[Completion]>>>,
 6262        cx: &mut Context<Self>,
 6263    ) -> Task<Result<bool>> {
 6264        let client = self.upstream_client();
 6265        let buffer_id = buffer.read(cx).remote_id();
 6266        let buffer_snapshot = buffer.read(cx).snapshot();
 6267
 6268        if !self.check_if_capable_for_proto_request(
 6269            &buffer,
 6270            GetCompletions::can_resolve_completions,
 6271            cx,
 6272        ) {
 6273            return Task::ready(Ok(false));
 6274        }
 6275        cx.spawn(async move |lsp_store, cx| {
 6276            let mut did_resolve = false;
 6277            if let Some((client, project_id)) = client {
 6278                for completion_index in completion_indices {
 6279                    let server_id = {
 6280                        let completion = &completions.borrow()[completion_index];
 6281                        completion.source.server_id()
 6282                    };
 6283                    if let Some(server_id) = server_id {
 6284                        if Self::resolve_completion_remote(
 6285                            project_id,
 6286                            server_id,
 6287                            buffer_id,
 6288                            completions.clone(),
 6289                            completion_index,
 6290                            client.clone(),
 6291                        )
 6292                        .await
 6293                        .log_err()
 6294                        .is_some()
 6295                        {
 6296                            did_resolve = true;
 6297                        }
 6298                    } else {
 6299                        resolve_word_completion(
 6300                            &buffer_snapshot,
 6301                            &mut completions.borrow_mut()[completion_index],
 6302                        );
 6303                    }
 6304                }
 6305            } else {
 6306                for completion_index in completion_indices {
 6307                    let server_id = {
 6308                        let completion = &completions.borrow()[completion_index];
 6309                        completion.source.server_id()
 6310                    };
 6311                    if let Some(server_id) = server_id {
 6312                        let server_and_adapter = lsp_store
 6313                            .read_with(cx, |lsp_store, _| {
 6314                                let server = lsp_store.language_server_for_id(server_id)?;
 6315                                let adapter =
 6316                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6317                                Some((server, adapter))
 6318                            })
 6319                            .ok()
 6320                            .flatten();
 6321                        let Some((server, adapter)) = server_and_adapter else {
 6322                            continue;
 6323                        };
 6324
 6325                        let resolved = Self::resolve_completion_local(
 6326                            server,
 6327                            completions.clone(),
 6328                            completion_index,
 6329                        )
 6330                        .await
 6331                        .log_err()
 6332                        .is_some();
 6333                        if resolved {
 6334                            Self::regenerate_completion_labels(
 6335                                adapter,
 6336                                &buffer_snapshot,
 6337                                completions.clone(),
 6338                                completion_index,
 6339                            )
 6340                            .await
 6341                            .log_err();
 6342                            did_resolve = true;
 6343                        }
 6344                    } else {
 6345                        resolve_word_completion(
 6346                            &buffer_snapshot,
 6347                            &mut completions.borrow_mut()[completion_index],
 6348                        );
 6349                    }
 6350                }
 6351            }
 6352
 6353            Ok(did_resolve)
 6354        })
 6355    }
 6356
 6357    async fn resolve_completion_local(
 6358        server: Arc<lsp::LanguageServer>,
 6359        completions: Rc<RefCell<Box<[Completion]>>>,
 6360        completion_index: usize,
 6361    ) -> Result<()> {
 6362        let server_id = server.server_id();
 6363        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6364            return Ok(());
 6365        }
 6366
 6367        let request = {
 6368            let completion = &completions.borrow()[completion_index];
 6369            match &completion.source {
 6370                CompletionSource::Lsp {
 6371                    lsp_completion,
 6372                    resolved,
 6373                    server_id: completion_server_id,
 6374                    ..
 6375                } => {
 6376                    if *resolved {
 6377                        return Ok(());
 6378                    }
 6379                    anyhow::ensure!(
 6380                        server_id == *completion_server_id,
 6381                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6382                    );
 6383                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6384                }
 6385                CompletionSource::BufferWord { .. }
 6386                | CompletionSource::Dap { .. }
 6387                | CompletionSource::Custom => {
 6388                    return Ok(());
 6389                }
 6390            }
 6391        };
 6392        let resolved_completion = request
 6393            .await
 6394            .into_response()
 6395            .context("resolve completion")?;
 6396
 6397        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6398        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6399
 6400        let mut completions = completions.borrow_mut();
 6401        let completion = &mut completions[completion_index];
 6402        if let CompletionSource::Lsp {
 6403            lsp_completion,
 6404            resolved,
 6405            server_id: completion_server_id,
 6406            ..
 6407        } = &mut completion.source
 6408        {
 6409            if *resolved {
 6410                return Ok(());
 6411            }
 6412            anyhow::ensure!(
 6413                server_id == *completion_server_id,
 6414                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6415            );
 6416            *lsp_completion = Box::new(resolved_completion);
 6417            *resolved = true;
 6418        }
 6419        Ok(())
 6420    }
 6421
 6422    async fn regenerate_completion_labels(
 6423        adapter: Arc<CachedLspAdapter>,
 6424        snapshot: &BufferSnapshot,
 6425        completions: Rc<RefCell<Box<[Completion]>>>,
 6426        completion_index: usize,
 6427    ) -> Result<()> {
 6428        let completion_item = completions.borrow()[completion_index]
 6429            .source
 6430            .lsp_completion(true)
 6431            .map(Cow::into_owned);
 6432        if let Some(lsp_documentation) = completion_item
 6433            .as_ref()
 6434            .and_then(|completion_item| completion_item.documentation.clone())
 6435        {
 6436            let mut completions = completions.borrow_mut();
 6437            let completion = &mut completions[completion_index];
 6438            completion.documentation = Some(lsp_documentation.into());
 6439        } else {
 6440            let mut completions = completions.borrow_mut();
 6441            let completion = &mut completions[completion_index];
 6442            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6443        }
 6444
 6445        let mut new_label = match completion_item {
 6446            Some(completion_item) => {
 6447                // 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
 6448                // So we have to update the label here anyway...
 6449                let language = snapshot.language();
 6450                match language {
 6451                    Some(language) => {
 6452                        adapter
 6453                            .labels_for_completions(
 6454                                std::slice::from_ref(&completion_item),
 6455                                language,
 6456                            )
 6457                            .await?
 6458                    }
 6459                    None => Vec::new(),
 6460                }
 6461                .pop()
 6462                .flatten()
 6463                .unwrap_or_else(|| {
 6464                    CodeLabel::fallback_for_completion(
 6465                        &completion_item,
 6466                        language.map(|language| language.as_ref()),
 6467                    )
 6468                })
 6469            }
 6470            None => CodeLabel::plain(
 6471                completions.borrow()[completion_index].new_text.clone(),
 6472                None,
 6473            ),
 6474        };
 6475        ensure_uniform_list_compatible_label(&mut new_label);
 6476
 6477        let mut completions = completions.borrow_mut();
 6478        let completion = &mut completions[completion_index];
 6479        if completion.label.filter_text() == new_label.filter_text() {
 6480            completion.label = new_label;
 6481        } else {
 6482            log::error!(
 6483                "Resolved completion changed display label from {} to {}. \
 6484                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6485                completion.label.text(),
 6486                new_label.text(),
 6487                completion.label.filter_text(),
 6488                new_label.filter_text()
 6489            );
 6490        }
 6491
 6492        Ok(())
 6493    }
 6494
 6495    async fn resolve_completion_remote(
 6496        project_id: u64,
 6497        server_id: LanguageServerId,
 6498        buffer_id: BufferId,
 6499        completions: Rc<RefCell<Box<[Completion]>>>,
 6500        completion_index: usize,
 6501        client: AnyProtoClient,
 6502    ) -> Result<()> {
 6503        let lsp_completion = {
 6504            let completion = &completions.borrow()[completion_index];
 6505            match &completion.source {
 6506                CompletionSource::Lsp {
 6507                    lsp_completion,
 6508                    resolved,
 6509                    server_id: completion_server_id,
 6510                    ..
 6511                } => {
 6512                    anyhow::ensure!(
 6513                        server_id == *completion_server_id,
 6514                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6515                    );
 6516                    if *resolved {
 6517                        return Ok(());
 6518                    }
 6519                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6520                }
 6521                CompletionSource::Custom
 6522                | CompletionSource::Dap { .. }
 6523                | CompletionSource::BufferWord { .. } => {
 6524                    return Ok(());
 6525                }
 6526            }
 6527        };
 6528        let request = proto::ResolveCompletionDocumentation {
 6529            project_id,
 6530            language_server_id: server_id.0 as u64,
 6531            lsp_completion,
 6532            buffer_id: buffer_id.into(),
 6533        };
 6534
 6535        let response = client
 6536            .request(request)
 6537            .await
 6538            .context("completion documentation resolve proto request")?;
 6539        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6540
 6541        let documentation = if response.documentation.is_empty() {
 6542            CompletionDocumentation::Undocumented
 6543        } else if response.documentation_is_markdown {
 6544            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6545        } else if response.documentation.lines().count() <= 1 {
 6546            CompletionDocumentation::SingleLine(response.documentation.into())
 6547        } else {
 6548            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6549        };
 6550
 6551        let mut completions = completions.borrow_mut();
 6552        let completion = &mut completions[completion_index];
 6553        completion.documentation = Some(documentation);
 6554        if let CompletionSource::Lsp {
 6555            insert_range,
 6556            lsp_completion,
 6557            resolved,
 6558            server_id: completion_server_id,
 6559            lsp_defaults: _,
 6560        } = &mut completion.source
 6561        {
 6562            let completion_insert_range = response
 6563                .old_insert_start
 6564                .and_then(deserialize_anchor)
 6565                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6566            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6567
 6568            if *resolved {
 6569                return Ok(());
 6570            }
 6571            anyhow::ensure!(
 6572                server_id == *completion_server_id,
 6573                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6574            );
 6575            *lsp_completion = Box::new(resolved_lsp_completion);
 6576            *resolved = true;
 6577        }
 6578
 6579        let replace_range = response
 6580            .old_replace_start
 6581            .and_then(deserialize_anchor)
 6582            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6583        if let Some((old_replace_start, old_replace_end)) = replace_range
 6584            && !response.new_text.is_empty()
 6585        {
 6586            completion.new_text = response.new_text;
 6587            completion.replace_range = old_replace_start..old_replace_end;
 6588        }
 6589
 6590        Ok(())
 6591    }
 6592
 6593    pub fn apply_additional_edits_for_completion(
 6594        &self,
 6595        buffer_handle: Entity<Buffer>,
 6596        completions: Rc<RefCell<Box<[Completion]>>>,
 6597        completion_index: usize,
 6598        push_to_history: bool,
 6599        cx: &mut Context<Self>,
 6600    ) -> Task<Result<Option<Transaction>>> {
 6601        if let Some((client, project_id)) = self.upstream_client() {
 6602            let buffer = buffer_handle.read(cx);
 6603            let buffer_id = buffer.remote_id();
 6604            cx.spawn(async move |_, cx| {
 6605                let request = {
 6606                    let completion = completions.borrow()[completion_index].clone();
 6607                    proto::ApplyCompletionAdditionalEdits {
 6608                        project_id,
 6609                        buffer_id: buffer_id.into(),
 6610                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6611                            replace_range: completion.replace_range,
 6612                            new_text: completion.new_text,
 6613                            source: completion.source,
 6614                        })),
 6615                    }
 6616                };
 6617
 6618                if let Some(transaction) = client.request(request).await?.transaction {
 6619                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6620                    buffer_handle
 6621                        .update(cx, |buffer, _| {
 6622                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6623                        })?
 6624                        .await?;
 6625                    if push_to_history {
 6626                        buffer_handle.update(cx, |buffer, _| {
 6627                            buffer.push_transaction(transaction.clone(), Instant::now());
 6628                            buffer.finalize_last_transaction();
 6629                        })?;
 6630                    }
 6631                    Ok(Some(transaction))
 6632                } else {
 6633                    Ok(None)
 6634                }
 6635            })
 6636        } else {
 6637            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6638                let completion = &completions.borrow()[completion_index];
 6639                let server_id = completion.source.server_id()?;
 6640                Some(
 6641                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6642                        .1
 6643                        .clone(),
 6644                )
 6645            }) else {
 6646                return Task::ready(Ok(None));
 6647            };
 6648
 6649            cx.spawn(async move |this, cx| {
 6650                Self::resolve_completion_local(
 6651                    server.clone(),
 6652                    completions.clone(),
 6653                    completion_index,
 6654                )
 6655                .await
 6656                .context("resolving completion")?;
 6657                let completion = completions.borrow()[completion_index].clone();
 6658                let additional_text_edits = completion
 6659                    .source
 6660                    .lsp_completion(true)
 6661                    .as_ref()
 6662                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6663                if let Some(edits) = additional_text_edits {
 6664                    let edits = this
 6665                        .update(cx, |this, cx| {
 6666                            this.as_local_mut().unwrap().edits_from_lsp(
 6667                                &buffer_handle,
 6668                                edits,
 6669                                server.server_id(),
 6670                                None,
 6671                                cx,
 6672                            )
 6673                        })?
 6674                        .await?;
 6675
 6676                    buffer_handle.update(cx, |buffer, cx| {
 6677                        buffer.finalize_last_transaction();
 6678                        buffer.start_transaction();
 6679
 6680                        for (range, text) in edits {
 6681                            let primary = &completion.replace_range;
 6682
 6683                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6684                            // and the primary completion is just an insertion (empty range), then this is likely
 6685                            // an auto-import scenario and should not be considered overlapping
 6686                            // https://github.com/zed-industries/zed/issues/26136
 6687                            let is_file_start_auto_import = {
 6688                                let snapshot = buffer.snapshot();
 6689                                let primary_start_point = primary.start.to_point(&snapshot);
 6690                                let range_start_point = range.start.to_point(&snapshot);
 6691
 6692                                let result = primary_start_point.row == 0
 6693                                    && primary_start_point.column == 0
 6694                                    && range_start_point.row == 0
 6695                                    && range_start_point.column == 0;
 6696
 6697                                result
 6698                            };
 6699
 6700                            let has_overlap = if is_file_start_auto_import {
 6701                                false
 6702                            } else {
 6703                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6704                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6705                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6706                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6707                                let result = start_within || end_within;
 6708                                result
 6709                            };
 6710
 6711                            //Skip additional edits which overlap with the primary completion edit
 6712                            //https://github.com/zed-industries/zed/pull/1871
 6713                            if !has_overlap {
 6714                                buffer.edit([(range, text)], None, cx);
 6715                            }
 6716                        }
 6717
 6718                        let transaction = if buffer.end_transaction(cx).is_some() {
 6719                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6720                            if !push_to_history {
 6721                                buffer.forget_transaction(transaction.id);
 6722                            }
 6723                            Some(transaction)
 6724                        } else {
 6725                            None
 6726                        };
 6727                        Ok(transaction)
 6728                    })?
 6729                } else {
 6730                    Ok(None)
 6731                }
 6732            })
 6733        }
 6734    }
 6735
 6736    pub fn pull_diagnostics(
 6737        &mut self,
 6738        buffer: Entity<Buffer>,
 6739        cx: &mut Context<Self>,
 6740    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6741        let buffer_id = buffer.read(cx).remote_id();
 6742
 6743        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6744            let mut suitable_capabilities = None;
 6745            // Are we capable for proto request?
 6746            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6747                &buffer,
 6748                |capabilities| {
 6749                    if let Some(caps) = &capabilities.diagnostic_provider {
 6750                        suitable_capabilities = Some(caps.clone());
 6751                        true
 6752                    } else {
 6753                        false
 6754                    }
 6755                },
 6756                cx,
 6757            );
 6758            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6759            let Some(dynamic_caps) = suitable_capabilities else {
 6760                return Task::ready(Ok(None));
 6761            };
 6762            assert!(any_server_has_diagnostics_provider);
 6763
 6764            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6765            let request = GetDocumentDiagnostics {
 6766                previous_result_id: None,
 6767                identifier,
 6768                registration_id: None,
 6769            };
 6770            let request_task = client.request_lsp(
 6771                upstream_project_id,
 6772                None,
 6773                LSP_REQUEST_TIMEOUT,
 6774                cx.background_executor().clone(),
 6775                request.to_proto(upstream_project_id, buffer.read(cx)),
 6776            );
 6777            cx.background_spawn(async move {
 6778                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6779                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6780                // Do not attempt to further process the dummy responses here.
 6781                let _response = request_task.await?;
 6782                Ok(None)
 6783            })
 6784        } else {
 6785            let servers = buffer.update(cx, |buffer, cx| {
 6786                self.running_language_servers_for_local_buffer(buffer, cx)
 6787                    .map(|(_, server)| server.clone())
 6788                    .collect::<Vec<_>>()
 6789            });
 6790
 6791            let pull_diagnostics = servers
 6792                .into_iter()
 6793                .flat_map(|server| {
 6794                    let result = maybe!({
 6795                        let local = self.as_local()?;
 6796                        let server_id = server.server_id();
 6797                        let providers_with_identifiers = local
 6798                            .language_server_dynamic_registrations
 6799                            .get(&server_id)
 6800                            .into_iter()
 6801                            .flat_map(|registrations| registrations.diagnostics.clone())
 6802                            .collect::<Vec<_>>();
 6803                        Some(
 6804                            providers_with_identifiers
 6805                                .into_iter()
 6806                                .map(|(registration_id, dynamic_caps)| {
 6807                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6808                                    let registration_id = registration_id.map(SharedString::from);
 6809                                    let result_id = self.result_id_for_buffer_pull(
 6810                                        server_id,
 6811                                        buffer_id,
 6812                                        &registration_id,
 6813                                        cx,
 6814                                    );
 6815                                    self.request_lsp(
 6816                                        buffer.clone(),
 6817                                        LanguageServerToQuery::Other(server_id),
 6818                                        GetDocumentDiagnostics {
 6819                                            previous_result_id: result_id,
 6820                                            registration_id,
 6821                                            identifier,
 6822                                        },
 6823                                        cx,
 6824                                    )
 6825                                })
 6826                                .collect::<Vec<_>>(),
 6827                        )
 6828                    });
 6829
 6830                    result.unwrap_or_default()
 6831                })
 6832                .collect::<Vec<_>>();
 6833
 6834            cx.background_spawn(async move {
 6835                let mut responses = Vec::new();
 6836                for diagnostics in join_all(pull_diagnostics).await {
 6837                    responses.extend(diagnostics?);
 6838                }
 6839                Ok(Some(responses))
 6840            })
 6841        }
 6842    }
 6843
 6844    pub fn applicable_inlay_chunks(
 6845        &mut self,
 6846        buffer: &Entity<Buffer>,
 6847        ranges: &[Range<text::Anchor>],
 6848        cx: &mut Context<Self>,
 6849    ) -> Vec<Range<BufferRow>> {
 6850        self.latest_lsp_data(buffer, cx)
 6851            .inlay_hints
 6852            .applicable_chunks(ranges)
 6853            .map(|chunk| chunk.row_range())
 6854            .collect()
 6855    }
 6856
 6857    pub fn invalidate_inlay_hints<'a>(
 6858        &'a mut self,
 6859        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6860    ) {
 6861        for buffer_id in for_buffers {
 6862            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6863                lsp_data.inlay_hints.clear();
 6864            }
 6865        }
 6866    }
 6867
 6868    pub fn inlay_hints(
 6869        &mut self,
 6870        invalidate: InvalidationStrategy,
 6871        buffer: Entity<Buffer>,
 6872        ranges: Vec<Range<text::Anchor>>,
 6873        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6874        cx: &mut Context<Self>,
 6875    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6876        let next_hint_id = self.next_hint_id.clone();
 6877        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6878        let query_version = lsp_data.buffer_version.clone();
 6879        let mut lsp_refresh_requested = false;
 6880        let for_server = if let InvalidationStrategy::RefreshRequested {
 6881            server_id,
 6882            request_id,
 6883        } = invalidate
 6884        {
 6885            let invalidated = lsp_data
 6886                .inlay_hints
 6887                .invalidate_for_server_refresh(server_id, request_id);
 6888            lsp_refresh_requested = invalidated;
 6889            Some(server_id)
 6890        } else {
 6891            None
 6892        };
 6893        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6894        let known_chunks = known_chunks
 6895            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6896            .map(|(_, known_chunks)| known_chunks)
 6897            .unwrap_or_default();
 6898
 6899        let mut hint_fetch_tasks = Vec::new();
 6900        let mut cached_inlay_hints = None;
 6901        let mut ranges_to_query = None;
 6902        let applicable_chunks = existing_inlay_hints
 6903            .applicable_chunks(ranges.as_slice())
 6904            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6905            .collect::<Vec<_>>();
 6906        if applicable_chunks.is_empty() {
 6907            return HashMap::default();
 6908        }
 6909
 6910        for row_chunk in applicable_chunks {
 6911            match (
 6912                existing_inlay_hints
 6913                    .cached_hints(&row_chunk)
 6914                    .filter(|_| !lsp_refresh_requested)
 6915                    .cloned(),
 6916                existing_inlay_hints
 6917                    .fetched_hints(&row_chunk)
 6918                    .as_ref()
 6919                    .filter(|_| !lsp_refresh_requested)
 6920                    .cloned(),
 6921            ) {
 6922                (None, None) => {
 6923                    let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
 6924                        continue;
 6925                    };
 6926                    ranges_to_query
 6927                        .get_or_insert_with(Vec::new)
 6928                        .push((row_chunk, chunk_range));
 6929                }
 6930                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6931                (Some(cached_hints), None) => {
 6932                    for (server_id, cached_hints) in cached_hints {
 6933                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6934                            cached_inlay_hints
 6935                                .get_or_insert_with(HashMap::default)
 6936                                .entry(row_chunk.row_range())
 6937                                .or_insert_with(HashMap::default)
 6938                                .entry(server_id)
 6939                                .or_insert_with(Vec::new)
 6940                                .extend(cached_hints);
 6941                        }
 6942                    }
 6943                }
 6944                (Some(cached_hints), Some(fetched_hints)) => {
 6945                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6946                    for (server_id, cached_hints) in cached_hints {
 6947                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6948                            cached_inlay_hints
 6949                                .get_or_insert_with(HashMap::default)
 6950                                .entry(row_chunk.row_range())
 6951                                .or_insert_with(HashMap::default)
 6952                                .entry(server_id)
 6953                                .or_insert_with(Vec::new)
 6954                                .extend(cached_hints);
 6955                        }
 6956                    }
 6957                }
 6958            }
 6959        }
 6960
 6961        if hint_fetch_tasks.is_empty()
 6962            && ranges_to_query
 6963                .as_ref()
 6964                .is_none_or(|ranges| ranges.is_empty())
 6965            && let Some(cached_inlay_hints) = cached_inlay_hints
 6966        {
 6967            cached_inlay_hints
 6968                .into_iter()
 6969                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6970                .collect()
 6971        } else {
 6972            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6973                let next_hint_id = next_hint_id.clone();
 6974                let buffer = buffer.clone();
 6975                let query_version = query_version.clone();
 6976                let new_inlay_hints = cx
 6977                    .spawn(async move |lsp_store, cx| {
 6978                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6979                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6980                        })?;
 6981                        new_fetch_task
 6982                            .await
 6983                            .and_then(|new_hints_by_server| {
 6984                                lsp_store.update(cx, |lsp_store, cx| {
 6985                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6986                                    let update_cache = lsp_data.buffer_version == query_version;
 6987                                    if new_hints_by_server.is_empty() {
 6988                                        if update_cache {
 6989                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6990                                        }
 6991                                        HashMap::default()
 6992                                    } else {
 6993                                        new_hints_by_server
 6994                                            .into_iter()
 6995                                            .map(|(server_id, new_hints)| {
 6996                                                let new_hints = new_hints
 6997                                                    .into_iter()
 6998                                                    .map(|new_hint| {
 6999                                                        (
 7000                                                            InlayId::Hint(next_hint_id.fetch_add(
 7001                                                                1,
 7002                                                                atomic::Ordering::AcqRel,
 7003                                                            )),
 7004                                                            new_hint,
 7005                                                        )
 7006                                                    })
 7007                                                    .collect::<Vec<_>>();
 7008                                                if update_cache {
 7009                                                    lsp_data.inlay_hints.insert_new_hints(
 7010                                                        chunk,
 7011                                                        server_id,
 7012                                                        new_hints.clone(),
 7013                                                    );
 7014                                                }
 7015                                                (server_id, new_hints)
 7016                                            })
 7017                                            .collect()
 7018                                    }
 7019                                })
 7020                            })
 7021                            .map_err(Arc::new)
 7022                    })
 7023                    .shared();
 7024
 7025                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7026                *fetch_task = Some(new_inlay_hints.clone());
 7027                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7028            }
 7029
 7030            cached_inlay_hints
 7031                .unwrap_or_default()
 7032                .into_iter()
 7033                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7034                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7035                    (
 7036                        chunk.row_range(),
 7037                        cx.spawn(async move |_, _| {
 7038                            hints_fetch.await.map_err(|e| {
 7039                                if e.error_code() != ErrorCode::Internal {
 7040                                    anyhow!(e.error_code())
 7041                                } else {
 7042                                    anyhow!("{e:#}")
 7043                                }
 7044                            })
 7045                        }),
 7046                    )
 7047                }))
 7048                .collect()
 7049        }
 7050    }
 7051
 7052    fn fetch_inlay_hints(
 7053        &mut self,
 7054        for_server: Option<LanguageServerId>,
 7055        buffer: &Entity<Buffer>,
 7056        range: Range<Anchor>,
 7057        cx: &mut Context<Self>,
 7058    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7059        let request = InlayHints {
 7060            range: range.clone(),
 7061        };
 7062        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7063            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7064                return Task::ready(Ok(HashMap::default()));
 7065            }
 7066            let request_task = upstream_client.request_lsp(
 7067                project_id,
 7068                for_server.map(|id| id.to_proto()),
 7069                LSP_REQUEST_TIMEOUT,
 7070                cx.background_executor().clone(),
 7071                request.to_proto(project_id, buffer.read(cx)),
 7072            );
 7073            let buffer = buffer.clone();
 7074            cx.spawn(async move |weak_lsp_store, cx| {
 7075                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7076                    return Ok(HashMap::default());
 7077                };
 7078                let Some(responses) = request_task.await? else {
 7079                    return Ok(HashMap::default());
 7080                };
 7081
 7082                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7083                    let lsp_store = lsp_store.clone();
 7084                    let buffer = buffer.clone();
 7085                    let cx = cx.clone();
 7086                    let request = request.clone();
 7087                    async move {
 7088                        (
 7089                            LanguageServerId::from_proto(response.server_id),
 7090                            request
 7091                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7092                                .await,
 7093                        )
 7094                    }
 7095                }))
 7096                .await;
 7097
 7098                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 7099                let mut has_errors = false;
 7100                let inlay_hints = inlay_hints
 7101                    .into_iter()
 7102                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7103                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7104                        Err(e) => {
 7105                            has_errors = true;
 7106                            log::error!("{e:#}");
 7107                            None
 7108                        }
 7109                    })
 7110                    .map(|(server_id, mut new_hints)| {
 7111                        new_hints.retain(|hint| {
 7112                            hint.position.is_valid(&buffer_snapshot)
 7113                                && range.start.is_valid(&buffer_snapshot)
 7114                                && range.end.is_valid(&buffer_snapshot)
 7115                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7116                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7117                        });
 7118                        (server_id, new_hints)
 7119                    })
 7120                    .collect::<HashMap<_, _>>();
 7121                anyhow::ensure!(
 7122                    !has_errors || !inlay_hints.is_empty(),
 7123                    "Failed to fetch inlay hints"
 7124                );
 7125                Ok(inlay_hints)
 7126            })
 7127        } else {
 7128            let inlay_hints_task = match for_server {
 7129                Some(server_id) => {
 7130                    let server_task = self.request_lsp(
 7131                        buffer.clone(),
 7132                        LanguageServerToQuery::Other(server_id),
 7133                        request,
 7134                        cx,
 7135                    );
 7136                    cx.background_spawn(async move {
 7137                        let mut responses = Vec::new();
 7138                        match server_task.await {
 7139                            Ok(response) => responses.push((server_id, response)),
 7140                            // rust-analyzer likes to error with this when its still loading up
 7141                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7142                            Err(e) => log::error!(
 7143                                "Error handling response for inlay hints request: {e:#}"
 7144                            ),
 7145                        }
 7146                        responses
 7147                    })
 7148                }
 7149                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7150            };
 7151            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7152            cx.background_spawn(async move {
 7153                Ok(inlay_hints_task
 7154                    .await
 7155                    .into_iter()
 7156                    .map(|(server_id, mut new_hints)| {
 7157                        new_hints.retain(|hint| {
 7158                            hint.position.is_valid(&buffer_snapshot)
 7159                                && range.start.is_valid(&buffer_snapshot)
 7160                                && range.end.is_valid(&buffer_snapshot)
 7161                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7162                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7163                        });
 7164                        (server_id, new_hints)
 7165                    })
 7166                    .collect())
 7167            })
 7168        }
 7169    }
 7170
 7171    pub fn pull_diagnostics_for_buffer(
 7172        &mut self,
 7173        buffer: Entity<Buffer>,
 7174        cx: &mut Context<Self>,
 7175    ) -> Task<anyhow::Result<()>> {
 7176        let diagnostics = self.pull_diagnostics(buffer, cx);
 7177        cx.spawn(async move |lsp_store, cx| {
 7178            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7179                return Ok(());
 7180            };
 7181            lsp_store.update(cx, |lsp_store, cx| {
 7182                if lsp_store.as_local().is_none() {
 7183                    return;
 7184                }
 7185
 7186                let mut unchanged_buffers = HashMap::default();
 7187                let server_diagnostics_updates = diagnostics
 7188                    .into_iter()
 7189                    .filter_map(|diagnostics_set| match diagnostics_set {
 7190                        LspPullDiagnostics::Response {
 7191                            server_id,
 7192                            uri,
 7193                            diagnostics,
 7194                            registration_id,
 7195                        } => Some((server_id, uri, diagnostics, registration_id)),
 7196                        LspPullDiagnostics::Default => None,
 7197                    })
 7198                    .fold(
 7199                        HashMap::default(),
 7200                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7201                            let (result_id, diagnostics) = match diagnostics {
 7202                                PulledDiagnostics::Unchanged { result_id } => {
 7203                                    unchanged_buffers
 7204                                        .entry(new_registration_id.clone())
 7205                                        .or_insert_with(HashSet::default)
 7206                                        .insert(uri.clone());
 7207                                    (Some(result_id), Vec::new())
 7208                                }
 7209                                PulledDiagnostics::Changed {
 7210                                    result_id,
 7211                                    diagnostics,
 7212                                } => (result_id, diagnostics),
 7213                            };
 7214                            let disk_based_sources = Cow::Owned(
 7215                                lsp_store
 7216                                    .language_server_adapter_for_id(server_id)
 7217                                    .as_ref()
 7218                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7219                                    .unwrap_or(&[])
 7220                                    .to_vec(),
 7221                            );
 7222                            acc.entry(server_id)
 7223                                .or_insert_with(HashMap::default)
 7224                                .entry(new_registration_id.clone())
 7225                                .or_insert_with(Vec::new)
 7226                                .push(DocumentDiagnosticsUpdate {
 7227                                    server_id,
 7228                                    diagnostics: lsp::PublishDiagnosticsParams {
 7229                                        uri,
 7230                                        diagnostics,
 7231                                        version: None,
 7232                                    },
 7233                                    result_id,
 7234                                    disk_based_sources,
 7235                                    registration_id: new_registration_id,
 7236                                });
 7237                            acc
 7238                        },
 7239                    );
 7240
 7241                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7242                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7243                        lsp_store
 7244                            .merge_lsp_diagnostics(
 7245                                DiagnosticSourceKind::Pulled,
 7246                                diagnostic_updates,
 7247                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7248                                    DiagnosticSourceKind::Pulled => {
 7249                                        old_diagnostic.registration_id != registration_id
 7250                                            || unchanged_buffers
 7251                                                .get(&old_diagnostic.registration_id)
 7252                                                .is_some_and(|unchanged_buffers| {
 7253                                                    unchanged_buffers.contains(&document_uri)
 7254                                                })
 7255                                    }
 7256                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7257                                        true
 7258                                    }
 7259                                },
 7260                                cx,
 7261                            )
 7262                            .log_err();
 7263                    }
 7264                }
 7265            })
 7266        })
 7267    }
 7268
 7269    pub fn document_colors(
 7270        &mut self,
 7271        known_cache_version: Option<usize>,
 7272        buffer: Entity<Buffer>,
 7273        cx: &mut Context<Self>,
 7274    ) -> Option<DocumentColorTask> {
 7275        let version_queried_for = buffer.read(cx).version();
 7276        let buffer_id = buffer.read(cx).remote_id();
 7277
 7278        let current_language_servers = self.as_local().map(|local| {
 7279            local
 7280                .buffers_opened_in_servers
 7281                .get(&buffer_id)
 7282                .cloned()
 7283                .unwrap_or_default()
 7284        });
 7285
 7286        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7287            if let Some(cached_colors) = &lsp_data.document_colors {
 7288                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7289                    let has_different_servers =
 7290                        current_language_servers.is_some_and(|current_language_servers| {
 7291                            current_language_servers
 7292                                != cached_colors.colors.keys().copied().collect()
 7293                        });
 7294                    if !has_different_servers {
 7295                        let cache_version = cached_colors.cache_version;
 7296                        if Some(cache_version) == known_cache_version {
 7297                            return None;
 7298                        } else {
 7299                            return Some(
 7300                                Task::ready(Ok(DocumentColors {
 7301                                    colors: cached_colors
 7302                                        .colors
 7303                                        .values()
 7304                                        .flatten()
 7305                                        .cloned()
 7306                                        .collect(),
 7307                                    cache_version: Some(cache_version),
 7308                                }))
 7309                                .shared(),
 7310                            );
 7311                        }
 7312                    }
 7313                }
 7314            }
 7315        }
 7316
 7317        let color_lsp_data = self
 7318            .latest_lsp_data(&buffer, cx)
 7319            .document_colors
 7320            .get_or_insert_default();
 7321        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7322            && !version_queried_for.changed_since(updating_for)
 7323        {
 7324            return Some(running_update.clone());
 7325        }
 7326        let buffer_version_queried_for = version_queried_for.clone();
 7327        let new_task = cx
 7328            .spawn(async move |lsp_store, cx| {
 7329                cx.background_executor()
 7330                    .timer(Duration::from_millis(30))
 7331                    .await;
 7332                let fetched_colors = lsp_store
 7333                    .update(cx, |lsp_store, cx| {
 7334                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7335                    })?
 7336                    .await
 7337                    .context("fetching document colors")
 7338                    .map_err(Arc::new);
 7339                let fetched_colors = match fetched_colors {
 7340                    Ok(fetched_colors) => {
 7341                        if Some(true)
 7342                            == buffer
 7343                                .update(cx, |buffer, _| {
 7344                                    buffer.version() != buffer_version_queried_for
 7345                                })
 7346                                .ok()
 7347                        {
 7348                            return Ok(DocumentColors::default());
 7349                        }
 7350                        fetched_colors
 7351                    }
 7352                    Err(e) => {
 7353                        lsp_store
 7354                            .update(cx, |lsp_store, _| {
 7355                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7356                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7357                                        document_colors.colors_update = None;
 7358                                    }
 7359                                }
 7360                            })
 7361                            .ok();
 7362                        return Err(e);
 7363                    }
 7364                };
 7365
 7366                lsp_store
 7367                    .update(cx, |lsp_store, cx| {
 7368                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7369                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7370
 7371                        if let Some(fetched_colors) = fetched_colors {
 7372                            if lsp_data.buffer_version == buffer_version_queried_for {
 7373                                lsp_colors.colors.extend(fetched_colors);
 7374                                lsp_colors.cache_version += 1;
 7375                            } else if !lsp_data
 7376                                .buffer_version
 7377                                .changed_since(&buffer_version_queried_for)
 7378                            {
 7379                                lsp_data.buffer_version = buffer_version_queried_for;
 7380                                lsp_colors.colors = fetched_colors;
 7381                                lsp_colors.cache_version += 1;
 7382                            }
 7383                        }
 7384                        lsp_colors.colors_update = None;
 7385                        let colors = lsp_colors
 7386                            .colors
 7387                            .values()
 7388                            .flatten()
 7389                            .cloned()
 7390                            .collect::<HashSet<_>>();
 7391                        DocumentColors {
 7392                            colors,
 7393                            cache_version: Some(lsp_colors.cache_version),
 7394                        }
 7395                    })
 7396                    .map_err(Arc::new)
 7397            })
 7398            .shared();
 7399        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7400        Some(new_task)
 7401    }
 7402
 7403    fn fetch_document_colors_for_buffer(
 7404        &mut self,
 7405        buffer: &Entity<Buffer>,
 7406        cx: &mut Context<Self>,
 7407    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7408        if let Some((client, project_id)) = self.upstream_client() {
 7409            let request = GetDocumentColor {};
 7410            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7411                return Task::ready(Ok(None));
 7412            }
 7413
 7414            let request_task = client.request_lsp(
 7415                project_id,
 7416                None,
 7417                LSP_REQUEST_TIMEOUT,
 7418                cx.background_executor().clone(),
 7419                request.to_proto(project_id, buffer.read(cx)),
 7420            );
 7421            let buffer = buffer.clone();
 7422            cx.spawn(async move |lsp_store, cx| {
 7423                let Some(lsp_store) = lsp_store.upgrade() else {
 7424                    return Ok(None);
 7425                };
 7426                let colors = join_all(
 7427                    request_task
 7428                        .await
 7429                        .log_err()
 7430                        .flatten()
 7431                        .map(|response| response.payload)
 7432                        .unwrap_or_default()
 7433                        .into_iter()
 7434                        .map(|color_response| {
 7435                            let response = request.response_from_proto(
 7436                                color_response.response,
 7437                                lsp_store.clone(),
 7438                                buffer.clone(),
 7439                                cx.clone(),
 7440                            );
 7441                            async move {
 7442                                (
 7443                                    LanguageServerId::from_proto(color_response.server_id),
 7444                                    response.await.log_err().unwrap_or_default(),
 7445                                )
 7446                            }
 7447                        }),
 7448                )
 7449                .await
 7450                .into_iter()
 7451                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7452                    acc.entry(server_id)
 7453                        .or_insert_with(HashSet::default)
 7454                        .extend(colors);
 7455                    acc
 7456                });
 7457                Ok(Some(colors))
 7458            })
 7459        } else {
 7460            let document_colors_task =
 7461                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7462            cx.background_spawn(async move {
 7463                Ok(Some(
 7464                    document_colors_task
 7465                        .await
 7466                        .into_iter()
 7467                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7468                            acc.entry(server_id)
 7469                                .or_insert_with(HashSet::default)
 7470                                .extend(colors);
 7471                            acc
 7472                        })
 7473                        .into_iter()
 7474                        .collect(),
 7475                ))
 7476            })
 7477        }
 7478    }
 7479
 7480    pub fn signature_help<T: ToPointUtf16>(
 7481        &mut self,
 7482        buffer: &Entity<Buffer>,
 7483        position: T,
 7484        cx: &mut Context<Self>,
 7485    ) -> Task<Option<Vec<SignatureHelp>>> {
 7486        let position = position.to_point_utf16(buffer.read(cx));
 7487
 7488        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7489            let request = GetSignatureHelp { position };
 7490            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7491                return Task::ready(None);
 7492            }
 7493            let request_task = client.request_lsp(
 7494                upstream_project_id,
 7495                None,
 7496                LSP_REQUEST_TIMEOUT,
 7497                cx.background_executor().clone(),
 7498                request.to_proto(upstream_project_id, buffer.read(cx)),
 7499            );
 7500            let buffer = buffer.clone();
 7501            cx.spawn(async move |weak_lsp_store, cx| {
 7502                let lsp_store = weak_lsp_store.upgrade()?;
 7503                let signatures = join_all(
 7504                    request_task
 7505                        .await
 7506                        .log_err()
 7507                        .flatten()
 7508                        .map(|response| response.payload)
 7509                        .unwrap_or_default()
 7510                        .into_iter()
 7511                        .map(|response| {
 7512                            let response = GetSignatureHelp { position }.response_from_proto(
 7513                                response.response,
 7514                                lsp_store.clone(),
 7515                                buffer.clone(),
 7516                                cx.clone(),
 7517                            );
 7518                            async move { response.await.log_err().flatten() }
 7519                        }),
 7520                )
 7521                .await
 7522                .into_iter()
 7523                .flatten()
 7524                .collect();
 7525                Some(signatures)
 7526            })
 7527        } else {
 7528            let all_actions_task = self.request_multiple_lsp_locally(
 7529                buffer,
 7530                Some(position),
 7531                GetSignatureHelp { position },
 7532                cx,
 7533            );
 7534            cx.background_spawn(async move {
 7535                Some(
 7536                    all_actions_task
 7537                        .await
 7538                        .into_iter()
 7539                        .flat_map(|(_, actions)| actions)
 7540                        .collect::<Vec<_>>(),
 7541                )
 7542            })
 7543        }
 7544    }
 7545
 7546    pub fn hover(
 7547        &mut self,
 7548        buffer: &Entity<Buffer>,
 7549        position: PointUtf16,
 7550        cx: &mut Context<Self>,
 7551    ) -> Task<Option<Vec<Hover>>> {
 7552        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7553            let request = GetHover { position };
 7554            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7555                return Task::ready(None);
 7556            }
 7557            let request_task = client.request_lsp(
 7558                upstream_project_id,
 7559                None,
 7560                LSP_REQUEST_TIMEOUT,
 7561                cx.background_executor().clone(),
 7562                request.to_proto(upstream_project_id, buffer.read(cx)),
 7563            );
 7564            let buffer = buffer.clone();
 7565            cx.spawn(async move |weak_lsp_store, cx| {
 7566                let lsp_store = weak_lsp_store.upgrade()?;
 7567                let hovers = join_all(
 7568                    request_task
 7569                        .await
 7570                        .log_err()
 7571                        .flatten()
 7572                        .map(|response| response.payload)
 7573                        .unwrap_or_default()
 7574                        .into_iter()
 7575                        .map(|response| {
 7576                            let response = GetHover { position }.response_from_proto(
 7577                                response.response,
 7578                                lsp_store.clone(),
 7579                                buffer.clone(),
 7580                                cx.clone(),
 7581                            );
 7582                            async move {
 7583                                response
 7584                                    .await
 7585                                    .log_err()
 7586                                    .flatten()
 7587                                    .and_then(remove_empty_hover_blocks)
 7588                            }
 7589                        }),
 7590                )
 7591                .await
 7592                .into_iter()
 7593                .flatten()
 7594                .collect();
 7595                Some(hovers)
 7596            })
 7597        } else {
 7598            let all_actions_task = self.request_multiple_lsp_locally(
 7599                buffer,
 7600                Some(position),
 7601                GetHover { position },
 7602                cx,
 7603            );
 7604            cx.background_spawn(async move {
 7605                Some(
 7606                    all_actions_task
 7607                        .await
 7608                        .into_iter()
 7609                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7610                        .collect::<Vec<Hover>>(),
 7611                )
 7612            })
 7613        }
 7614    }
 7615
 7616    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7617        let language_registry = self.languages.clone();
 7618
 7619        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7620            let request = upstream_client.request(proto::GetProjectSymbols {
 7621                project_id: *project_id,
 7622                query: query.to_string(),
 7623            });
 7624            cx.foreground_executor().spawn(async move {
 7625                let response = request.await?;
 7626                let mut symbols = Vec::new();
 7627                let core_symbols = response
 7628                    .symbols
 7629                    .into_iter()
 7630                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7631                    .collect::<Vec<_>>();
 7632                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7633                    .await;
 7634                Ok(symbols)
 7635            })
 7636        } else if let Some(local) = self.as_local() {
 7637            struct WorkspaceSymbolsResult {
 7638                server_id: LanguageServerId,
 7639                lsp_adapter: Arc<CachedLspAdapter>,
 7640                worktree: WeakEntity<Worktree>,
 7641                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7642            }
 7643
 7644            let mut requests = Vec::new();
 7645            let mut requested_servers = BTreeSet::new();
 7646            for (seed, state) in local.language_server_ids.iter() {
 7647                let Some(worktree_handle) = self
 7648                    .worktree_store
 7649                    .read(cx)
 7650                    .worktree_for_id(seed.worktree_id, cx)
 7651                else {
 7652                    continue;
 7653                };
 7654                let worktree = worktree_handle.read(cx);
 7655                if !worktree.is_visible() {
 7656                    continue;
 7657                }
 7658
 7659                if !requested_servers.insert(state.id) {
 7660                    continue;
 7661                }
 7662
 7663                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7664                    Some(LanguageServerState::Running {
 7665                        adapter, server, ..
 7666                    }) => (adapter.clone(), server),
 7667
 7668                    _ => continue,
 7669                };
 7670                let supports_workspace_symbol_request =
 7671                    match server.capabilities().workspace_symbol_provider {
 7672                        Some(OneOf::Left(supported)) => supported,
 7673                        Some(OneOf::Right(_)) => true,
 7674                        None => false,
 7675                    };
 7676                if !supports_workspace_symbol_request {
 7677                    continue;
 7678                }
 7679                let worktree_handle = worktree_handle.clone();
 7680                let server_id = server.server_id();
 7681                requests.push(
 7682                        server
 7683                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7684                                lsp::WorkspaceSymbolParams {
 7685                                    query: query.to_string(),
 7686                                    ..Default::default()
 7687                                },
 7688                            )
 7689                            .map(move |response| {
 7690                                let lsp_symbols = response.into_response()
 7691                                    .context("workspace symbols request")
 7692                                    .log_err()
 7693                                    .flatten()
 7694                                    .map(|symbol_response| match symbol_response {
 7695                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7696                                            flat_responses.into_iter().map(|lsp_symbol| {
 7697                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7698                                            }).collect::<Vec<_>>()
 7699                                        }
 7700                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7701                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7702                                                let location = match lsp_symbol.location {
 7703                                                    OneOf::Left(location) => location,
 7704                                                    OneOf::Right(_) => {
 7705                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7706                                                        return None
 7707                                                    }
 7708                                                };
 7709                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7710                                            }).collect::<Vec<_>>()
 7711                                        }
 7712                                    }).unwrap_or_default();
 7713
 7714                                WorkspaceSymbolsResult {
 7715                                    server_id,
 7716                                    lsp_adapter,
 7717                                    worktree: worktree_handle.downgrade(),
 7718                                    lsp_symbols,
 7719                                }
 7720                            }),
 7721                    );
 7722            }
 7723
 7724            cx.spawn(async move |this, cx| {
 7725                let responses = futures::future::join_all(requests).await;
 7726                let this = match this.upgrade() {
 7727                    Some(this) => this,
 7728                    None => return Ok(Vec::new()),
 7729                };
 7730
 7731                let mut symbols = Vec::new();
 7732                for result in responses {
 7733                    let core_symbols = this.update(cx, |this, cx| {
 7734                        result
 7735                            .lsp_symbols
 7736                            .into_iter()
 7737                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7738                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7739                                let source_worktree = result.worktree.upgrade()?;
 7740                                let source_worktree_id = source_worktree.read(cx).id();
 7741
 7742                                let path = if let Some((tree, rel_path)) =
 7743                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7744                                {
 7745                                    let worktree_id = tree.read(cx).id();
 7746                                    SymbolLocation::InProject(ProjectPath {
 7747                                        worktree_id,
 7748                                        path: rel_path,
 7749                                    })
 7750                                } else {
 7751                                    SymbolLocation::OutsideProject {
 7752                                        signature: this.symbol_signature(&abs_path),
 7753                                        abs_path: abs_path.into(),
 7754                                    }
 7755                                };
 7756
 7757                                Some(CoreSymbol {
 7758                                    source_language_server_id: result.server_id,
 7759                                    language_server_name: result.lsp_adapter.name.clone(),
 7760                                    source_worktree_id,
 7761                                    path,
 7762                                    kind: symbol_kind,
 7763                                    name: symbol_name,
 7764                                    range: range_from_lsp(symbol_location.range),
 7765                                })
 7766                            })
 7767                            .collect()
 7768                    })?;
 7769
 7770                    populate_labels_for_symbols(
 7771                        core_symbols,
 7772                        &language_registry,
 7773                        Some(result.lsp_adapter),
 7774                        &mut symbols,
 7775                    )
 7776                    .await;
 7777                }
 7778
 7779                Ok(symbols)
 7780            })
 7781        } else {
 7782            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7783        }
 7784    }
 7785
 7786    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7787        let mut summary = DiagnosticSummary::default();
 7788        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7789            summary.error_count += path_summary.error_count;
 7790            summary.warning_count += path_summary.warning_count;
 7791        }
 7792        summary
 7793    }
 7794
 7795    /// Returns the diagnostic summary for a specific project path.
 7796    pub fn diagnostic_summary_for_path(
 7797        &self,
 7798        project_path: &ProjectPath,
 7799        _: &App,
 7800    ) -> DiagnosticSummary {
 7801        if let Some(summaries) = self
 7802            .diagnostic_summaries
 7803            .get(&project_path.worktree_id)
 7804            .and_then(|map| map.get(&project_path.path))
 7805        {
 7806            let (error_count, warning_count) = summaries.iter().fold(
 7807                (0, 0),
 7808                |(error_count, warning_count), (_language_server_id, summary)| {
 7809                    (
 7810                        error_count + summary.error_count,
 7811                        warning_count + summary.warning_count,
 7812                    )
 7813                },
 7814            );
 7815
 7816            DiagnosticSummary {
 7817                error_count,
 7818                warning_count,
 7819            }
 7820        } else {
 7821            DiagnosticSummary::default()
 7822        }
 7823    }
 7824
 7825    pub fn diagnostic_summaries<'a>(
 7826        &'a self,
 7827        include_ignored: bool,
 7828        cx: &'a App,
 7829    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7830        self.worktree_store
 7831            .read(cx)
 7832            .visible_worktrees(cx)
 7833            .filter_map(|worktree| {
 7834                let worktree = worktree.read(cx);
 7835                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7836            })
 7837            .flat_map(move |(worktree, summaries)| {
 7838                let worktree_id = worktree.id();
 7839                summaries
 7840                    .iter()
 7841                    .filter(move |(path, _)| {
 7842                        include_ignored
 7843                            || worktree
 7844                                .entry_for_path(path.as_ref())
 7845                                .is_some_and(|entry| !entry.is_ignored)
 7846                    })
 7847                    .flat_map(move |(path, summaries)| {
 7848                        summaries.iter().map(move |(server_id, summary)| {
 7849                            (
 7850                                ProjectPath {
 7851                                    worktree_id,
 7852                                    path: path.clone(),
 7853                                },
 7854                                *server_id,
 7855                                *summary,
 7856                            )
 7857                        })
 7858                    })
 7859            })
 7860    }
 7861
 7862    pub fn on_buffer_edited(
 7863        &mut self,
 7864        buffer: Entity<Buffer>,
 7865        cx: &mut Context<Self>,
 7866    ) -> Option<()> {
 7867        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7868            Some(
 7869                self.as_local()?
 7870                    .language_servers_for_buffer(buffer, cx)
 7871                    .map(|i| i.1.clone())
 7872                    .collect(),
 7873            )
 7874        })?;
 7875
 7876        let buffer = buffer.read(cx);
 7877        let file = File::from_dyn(buffer.file())?;
 7878        let abs_path = file.as_local()?.abs_path(cx);
 7879        let uri = lsp::Uri::from_file_path(&abs_path)
 7880            .ok()
 7881            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7882            .log_err()?;
 7883        let next_snapshot = buffer.text_snapshot();
 7884        for language_server in language_servers {
 7885            let language_server = language_server.clone();
 7886
 7887            let buffer_snapshots = self
 7888                .as_local_mut()?
 7889                .buffer_snapshots
 7890                .get_mut(&buffer.remote_id())
 7891                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7892            let previous_snapshot = buffer_snapshots.last()?;
 7893
 7894            let build_incremental_change = || {
 7895                buffer
 7896                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7897                        previous_snapshot.snapshot.version(),
 7898                    )
 7899                    .map(|edit| {
 7900                        let edit_start = edit.new.start.0;
 7901                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7902                        let new_text = next_snapshot
 7903                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7904                            .collect();
 7905                        lsp::TextDocumentContentChangeEvent {
 7906                            range: Some(lsp::Range::new(
 7907                                point_to_lsp(edit_start),
 7908                                point_to_lsp(edit_end),
 7909                            )),
 7910                            range_length: None,
 7911                            text: new_text,
 7912                        }
 7913                    })
 7914                    .collect()
 7915            };
 7916
 7917            let document_sync_kind = language_server
 7918                .capabilities()
 7919                .text_document_sync
 7920                .as_ref()
 7921                .and_then(|sync| match sync {
 7922                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7923                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7924                });
 7925
 7926            let content_changes: Vec<_> = match document_sync_kind {
 7927                Some(lsp::TextDocumentSyncKind::FULL) => {
 7928                    vec![lsp::TextDocumentContentChangeEvent {
 7929                        range: None,
 7930                        range_length: None,
 7931                        text: next_snapshot.text(),
 7932                    }]
 7933                }
 7934                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7935                _ => {
 7936                    #[cfg(any(test, feature = "test-support"))]
 7937                    {
 7938                        build_incremental_change()
 7939                    }
 7940
 7941                    #[cfg(not(any(test, feature = "test-support")))]
 7942                    {
 7943                        continue;
 7944                    }
 7945                }
 7946            };
 7947
 7948            let next_version = previous_snapshot.version + 1;
 7949            buffer_snapshots.push(LspBufferSnapshot {
 7950                version: next_version,
 7951                snapshot: next_snapshot.clone(),
 7952            });
 7953
 7954            language_server
 7955                .notify::<lsp::notification::DidChangeTextDocument>(
 7956                    lsp::DidChangeTextDocumentParams {
 7957                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7958                            uri.clone(),
 7959                            next_version,
 7960                        ),
 7961                        content_changes,
 7962                    },
 7963                )
 7964                .ok();
 7965            self.pull_workspace_diagnostics(language_server.server_id());
 7966        }
 7967
 7968        None
 7969    }
 7970
 7971    pub fn on_buffer_saved(
 7972        &mut self,
 7973        buffer: Entity<Buffer>,
 7974        cx: &mut Context<Self>,
 7975    ) -> Option<()> {
 7976        let file = File::from_dyn(buffer.read(cx).file())?;
 7977        let worktree_id = file.worktree_id(cx);
 7978        let abs_path = file.as_local()?.abs_path(cx);
 7979        let text_document = lsp::TextDocumentIdentifier {
 7980            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7981        };
 7982        let local = self.as_local()?;
 7983
 7984        for server in local.language_servers_for_worktree(worktree_id) {
 7985            if let Some(include_text) = include_text(server.as_ref()) {
 7986                let text = if include_text {
 7987                    Some(buffer.read(cx).text())
 7988                } else {
 7989                    None
 7990                };
 7991                server
 7992                    .notify::<lsp::notification::DidSaveTextDocument>(
 7993                        lsp::DidSaveTextDocumentParams {
 7994                            text_document: text_document.clone(),
 7995                            text,
 7996                        },
 7997                    )
 7998                    .ok();
 7999            }
 8000        }
 8001
 8002        let language_servers = buffer.update(cx, |buffer, cx| {
 8003            local.language_server_ids_for_buffer(buffer, cx)
 8004        });
 8005        for language_server_id in language_servers {
 8006            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8007        }
 8008
 8009        None
 8010    }
 8011
 8012    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8013        maybe!(async move {
 8014            let mut refreshed_servers = HashSet::default();
 8015            let servers = lsp_store
 8016                .update(cx, |lsp_store, cx| {
 8017                    let local = lsp_store.as_local()?;
 8018
 8019                    let servers = local
 8020                        .language_server_ids
 8021                        .iter()
 8022                        .filter_map(|(seed, state)| {
 8023                            let worktree = lsp_store
 8024                                .worktree_store
 8025                                .read(cx)
 8026                                .worktree_for_id(seed.worktree_id, cx);
 8027                            let delegate: Arc<dyn LspAdapterDelegate> =
 8028                                worktree.map(|worktree| {
 8029                                    LocalLspAdapterDelegate::new(
 8030                                        local.languages.clone(),
 8031                                        &local.environment,
 8032                                        cx.weak_entity(),
 8033                                        &worktree,
 8034                                        local.http_client.clone(),
 8035                                        local.fs.clone(),
 8036                                        cx,
 8037                                    )
 8038                                })?;
 8039                            let server_id = state.id;
 8040
 8041                            let states = local.language_servers.get(&server_id)?;
 8042
 8043                            match states {
 8044                                LanguageServerState::Starting { .. } => None,
 8045                                LanguageServerState::Running {
 8046                                    adapter, server, ..
 8047                                } => {
 8048                                    let adapter = adapter.clone();
 8049                                    let server = server.clone();
 8050                                    refreshed_servers.insert(server.name());
 8051                                    let toolchain = seed.toolchain.clone();
 8052                                    Some(cx.spawn(async move |_, cx| {
 8053                                        let settings =
 8054                                            LocalLspStore::workspace_configuration_for_adapter(
 8055                                                adapter.adapter.clone(),
 8056                                                &delegate,
 8057                                                toolchain,
 8058                                                None,
 8059                                                cx,
 8060                                            )
 8061                                            .await
 8062                                            .ok()?;
 8063                                        server
 8064                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8065                                                lsp::DidChangeConfigurationParams { settings },
 8066                                            )
 8067                                            .ok()?;
 8068                                        Some(())
 8069                                    }))
 8070                                }
 8071                            }
 8072                        })
 8073                        .collect::<Vec<_>>();
 8074
 8075                    Some(servers)
 8076                })
 8077                .ok()
 8078                .flatten()?;
 8079
 8080            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8081            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8082            // to stop and unregister its language server wrapper.
 8083            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8084            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8085            let _: Vec<Option<()>> = join_all(servers).await;
 8086
 8087            Some(())
 8088        })
 8089        .await;
 8090    }
 8091
 8092    fn maintain_workspace_config(
 8093        external_refresh_requests: watch::Receiver<()>,
 8094        cx: &mut Context<Self>,
 8095    ) -> Task<Result<()>> {
 8096        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8097        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8098
 8099        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8100            *settings_changed_tx.borrow_mut() = ();
 8101        });
 8102
 8103        let mut joint_future =
 8104            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8105        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8106        // - 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).
 8107        // - 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.
 8108        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8109        // - 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,
 8110        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8111        cx.spawn(async move |this, cx| {
 8112            while let Some(()) = joint_future.next().await {
 8113                this.update(cx, |this, cx| {
 8114                    this.refresh_server_tree(cx);
 8115                })
 8116                .ok();
 8117
 8118                Self::refresh_workspace_configurations(&this, cx).await;
 8119            }
 8120
 8121            drop(settings_observation);
 8122            anyhow::Ok(())
 8123        })
 8124    }
 8125
 8126    pub fn running_language_servers_for_local_buffer<'a>(
 8127        &'a self,
 8128        buffer: &Buffer,
 8129        cx: &mut App,
 8130    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8131        let local = self.as_local();
 8132        let language_server_ids = local
 8133            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8134            .unwrap_or_default();
 8135
 8136        language_server_ids
 8137            .into_iter()
 8138            .filter_map(
 8139                move |server_id| match local?.language_servers.get(&server_id)? {
 8140                    LanguageServerState::Running {
 8141                        adapter, server, ..
 8142                    } => Some((adapter, server)),
 8143                    _ => None,
 8144                },
 8145            )
 8146    }
 8147
 8148    pub fn language_servers_for_local_buffer(
 8149        &self,
 8150        buffer: &Buffer,
 8151        cx: &mut App,
 8152    ) -> Vec<LanguageServerId> {
 8153        let local = self.as_local();
 8154        local
 8155            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8156            .unwrap_or_default()
 8157    }
 8158
 8159    pub fn language_server_for_local_buffer<'a>(
 8160        &'a self,
 8161        buffer: &'a Buffer,
 8162        server_id: LanguageServerId,
 8163        cx: &'a mut App,
 8164    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8165        self.as_local()?
 8166            .language_servers_for_buffer(buffer, cx)
 8167            .find(|(_, s)| s.server_id() == server_id)
 8168    }
 8169
 8170    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8171        self.diagnostic_summaries.remove(&id_to_remove);
 8172        if let Some(local) = self.as_local_mut() {
 8173            let to_remove = local.remove_worktree(id_to_remove, cx);
 8174            for server in to_remove {
 8175                self.language_server_statuses.remove(&server);
 8176            }
 8177        }
 8178    }
 8179
 8180    pub fn shared(
 8181        &mut self,
 8182        project_id: u64,
 8183        downstream_client: AnyProtoClient,
 8184        _: &mut Context<Self>,
 8185    ) {
 8186        self.downstream_client = Some((downstream_client.clone(), project_id));
 8187
 8188        for (server_id, status) in &self.language_server_statuses {
 8189            if let Some(server) = self.language_server_for_id(*server_id) {
 8190                downstream_client
 8191                    .send(proto::StartLanguageServer {
 8192                        project_id,
 8193                        server: Some(proto::LanguageServer {
 8194                            id: server_id.to_proto(),
 8195                            name: status.name.to_string(),
 8196                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8197                        }),
 8198                        capabilities: serde_json::to_string(&server.capabilities())
 8199                            .expect("serializing server LSP capabilities"),
 8200                    })
 8201                    .log_err();
 8202            }
 8203        }
 8204    }
 8205
 8206    pub fn disconnected_from_host(&mut self) {
 8207        self.downstream_client.take();
 8208    }
 8209
 8210    pub fn disconnected_from_ssh_remote(&mut self) {
 8211        if let LspStoreMode::Remote(RemoteLspStore {
 8212            upstream_client, ..
 8213        }) = &mut self.mode
 8214        {
 8215            upstream_client.take();
 8216        }
 8217    }
 8218
 8219    pub(crate) fn set_language_server_statuses_from_proto(
 8220        &mut self,
 8221        project: WeakEntity<Project>,
 8222        language_servers: Vec<proto::LanguageServer>,
 8223        server_capabilities: Vec<String>,
 8224        cx: &mut Context<Self>,
 8225    ) {
 8226        let lsp_logs = cx
 8227            .try_global::<GlobalLogStore>()
 8228            .map(|lsp_store| lsp_store.0.clone());
 8229
 8230        self.language_server_statuses = language_servers
 8231            .into_iter()
 8232            .zip(server_capabilities)
 8233            .map(|(server, server_capabilities)| {
 8234                let server_id = LanguageServerId(server.id as usize);
 8235                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8236                    self.lsp_server_capabilities
 8237                        .insert(server_id, server_capabilities);
 8238                }
 8239
 8240                let name = LanguageServerName::from_proto(server.name);
 8241                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8242
 8243                if let Some(lsp_logs) = &lsp_logs {
 8244                    lsp_logs.update(cx, |lsp_logs, cx| {
 8245                        lsp_logs.add_language_server(
 8246                            // Only remote clients get their language servers set from proto
 8247                            LanguageServerKind::Remote {
 8248                                project: project.clone(),
 8249                            },
 8250                            server_id,
 8251                            Some(name.clone()),
 8252                            worktree,
 8253                            None,
 8254                            cx,
 8255                        );
 8256                    });
 8257                }
 8258
 8259                (
 8260                    server_id,
 8261                    LanguageServerStatus {
 8262                        name,
 8263                        pending_work: Default::default(),
 8264                        has_pending_diagnostic_updates: false,
 8265                        progress_tokens: Default::default(),
 8266                        worktree,
 8267                        binary: None,
 8268                        configuration: None,
 8269                        workspace_folders: BTreeSet::new(),
 8270                    },
 8271                )
 8272            })
 8273            .collect();
 8274    }
 8275
 8276    #[cfg(test)]
 8277    pub fn update_diagnostic_entries(
 8278        &mut self,
 8279        server_id: LanguageServerId,
 8280        abs_path: PathBuf,
 8281        result_id: Option<SharedString>,
 8282        version: Option<i32>,
 8283        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8284        cx: &mut Context<Self>,
 8285    ) -> anyhow::Result<()> {
 8286        self.merge_diagnostic_entries(
 8287            vec![DocumentDiagnosticsUpdate {
 8288                diagnostics: DocumentDiagnostics {
 8289                    diagnostics,
 8290                    document_abs_path: abs_path,
 8291                    version,
 8292                },
 8293                result_id,
 8294                server_id,
 8295                disk_based_sources: Cow::Borrowed(&[]),
 8296                registration_id: None,
 8297            }],
 8298            |_, _, _| false,
 8299            cx,
 8300        )?;
 8301        Ok(())
 8302    }
 8303
 8304    pub fn merge_diagnostic_entries<'a>(
 8305        &mut self,
 8306        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8307        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8308        cx: &mut Context<Self>,
 8309    ) -> anyhow::Result<()> {
 8310        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8311        let mut updated_diagnostics_paths = HashMap::default();
 8312        for mut update in diagnostic_updates {
 8313            let abs_path = &update.diagnostics.document_abs_path;
 8314            let server_id = update.server_id;
 8315            let Some((worktree, relative_path)) =
 8316                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8317            else {
 8318                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8319                return Ok(());
 8320            };
 8321
 8322            let worktree_id = worktree.read(cx).id();
 8323            let project_path = ProjectPath {
 8324                worktree_id,
 8325                path: relative_path,
 8326            };
 8327
 8328            let document_uri = lsp::Uri::from_file_path(abs_path)
 8329                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8330            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8331                let snapshot = buffer_handle.read(cx).snapshot();
 8332                let buffer = buffer_handle.read(cx);
 8333                let reused_diagnostics = buffer
 8334                    .buffer_diagnostics(Some(server_id))
 8335                    .iter()
 8336                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8337                    .map(|v| {
 8338                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8339                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8340                        DiagnosticEntry {
 8341                            range: start..end,
 8342                            diagnostic: v.diagnostic.clone(),
 8343                        }
 8344                    })
 8345                    .collect::<Vec<_>>();
 8346
 8347                self.as_local_mut()
 8348                    .context("cannot merge diagnostics on a remote LspStore")?
 8349                    .update_buffer_diagnostics(
 8350                        &buffer_handle,
 8351                        server_id,
 8352                        Some(update.registration_id),
 8353                        update.result_id,
 8354                        update.diagnostics.version,
 8355                        update.diagnostics.diagnostics.clone(),
 8356                        reused_diagnostics.clone(),
 8357                        cx,
 8358                    )?;
 8359
 8360                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8361            } else if let Some(local) = self.as_local() {
 8362                let reused_diagnostics = local
 8363                    .diagnostics
 8364                    .get(&worktree_id)
 8365                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8366                    .and_then(|diagnostics_by_server_id| {
 8367                        diagnostics_by_server_id
 8368                            .binary_search_by_key(&server_id, |e| e.0)
 8369                            .ok()
 8370                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8371                    })
 8372                    .into_iter()
 8373                    .flatten()
 8374                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8375
 8376                update
 8377                    .diagnostics
 8378                    .diagnostics
 8379                    .extend(reused_diagnostics.cloned());
 8380            }
 8381
 8382            let updated = worktree.update(cx, |worktree, cx| {
 8383                self.update_worktree_diagnostics(
 8384                    worktree.id(),
 8385                    server_id,
 8386                    project_path.path.clone(),
 8387                    update.diagnostics.diagnostics,
 8388                    cx,
 8389                )
 8390            })?;
 8391            match updated {
 8392                ControlFlow::Continue(new_summary) => {
 8393                    if let Some((project_id, new_summary)) = new_summary {
 8394                        match &mut diagnostics_summary {
 8395                            Some(diagnostics_summary) => {
 8396                                diagnostics_summary
 8397                                    .more_summaries
 8398                                    .push(proto::DiagnosticSummary {
 8399                                        path: project_path.path.as_ref().to_proto(),
 8400                                        language_server_id: server_id.0 as u64,
 8401                                        error_count: new_summary.error_count,
 8402                                        warning_count: new_summary.warning_count,
 8403                                    })
 8404                            }
 8405                            None => {
 8406                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8407                                    project_id,
 8408                                    worktree_id: worktree_id.to_proto(),
 8409                                    summary: Some(proto::DiagnosticSummary {
 8410                                        path: project_path.path.as_ref().to_proto(),
 8411                                        language_server_id: server_id.0 as u64,
 8412                                        error_count: new_summary.error_count,
 8413                                        warning_count: new_summary.warning_count,
 8414                                    }),
 8415                                    more_summaries: Vec::new(),
 8416                                })
 8417                            }
 8418                        }
 8419                    }
 8420                    updated_diagnostics_paths
 8421                        .entry(server_id)
 8422                        .or_insert_with(Vec::new)
 8423                        .push(project_path);
 8424                }
 8425                ControlFlow::Break(()) => {}
 8426            }
 8427        }
 8428
 8429        if let Some((diagnostics_summary, (downstream_client, _))) =
 8430            diagnostics_summary.zip(self.downstream_client.as_ref())
 8431        {
 8432            downstream_client.send(diagnostics_summary).log_err();
 8433        }
 8434        for (server_id, paths) in updated_diagnostics_paths {
 8435            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8436        }
 8437        Ok(())
 8438    }
 8439
 8440    fn update_worktree_diagnostics(
 8441        &mut self,
 8442        worktree_id: WorktreeId,
 8443        server_id: LanguageServerId,
 8444        path_in_worktree: Arc<RelPath>,
 8445        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8446        _: &mut Context<Worktree>,
 8447    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8448        let local = match &mut self.mode {
 8449            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8450            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8451        };
 8452
 8453        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8454        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8455        let summaries_by_server_id = summaries_for_tree
 8456            .entry(path_in_worktree.clone())
 8457            .or_default();
 8458
 8459        let old_summary = summaries_by_server_id
 8460            .remove(&server_id)
 8461            .unwrap_or_default();
 8462
 8463        let new_summary = DiagnosticSummary::new(&diagnostics);
 8464        if diagnostics.is_empty() {
 8465            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8466            {
 8467                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8468                    diagnostics_by_server_id.remove(ix);
 8469                }
 8470                if diagnostics_by_server_id.is_empty() {
 8471                    diagnostics_for_tree.remove(&path_in_worktree);
 8472                }
 8473            }
 8474        } else {
 8475            summaries_by_server_id.insert(server_id, new_summary);
 8476            let diagnostics_by_server_id = diagnostics_for_tree
 8477                .entry(path_in_worktree.clone())
 8478                .or_default();
 8479            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8480                Ok(ix) => {
 8481                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8482                }
 8483                Err(ix) => {
 8484                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8485                }
 8486            }
 8487        }
 8488
 8489        if !old_summary.is_empty() || !new_summary.is_empty() {
 8490            if let Some((_, project_id)) = &self.downstream_client {
 8491                Ok(ControlFlow::Continue(Some((
 8492                    *project_id,
 8493                    proto::DiagnosticSummary {
 8494                        path: path_in_worktree.to_proto(),
 8495                        language_server_id: server_id.0 as u64,
 8496                        error_count: new_summary.error_count as u32,
 8497                        warning_count: new_summary.warning_count as u32,
 8498                    },
 8499                ))))
 8500            } else {
 8501                Ok(ControlFlow::Continue(None))
 8502            }
 8503        } else {
 8504            Ok(ControlFlow::Break(()))
 8505        }
 8506    }
 8507
 8508    pub fn open_buffer_for_symbol(
 8509        &mut self,
 8510        symbol: &Symbol,
 8511        cx: &mut Context<Self>,
 8512    ) -> Task<Result<Entity<Buffer>>> {
 8513        if let Some((client, project_id)) = self.upstream_client() {
 8514            let request = client.request(proto::OpenBufferForSymbol {
 8515                project_id,
 8516                symbol: Some(Self::serialize_symbol(symbol)),
 8517            });
 8518            cx.spawn(async move |this, cx| {
 8519                let response = request.await?;
 8520                let buffer_id = BufferId::new(response.buffer_id)?;
 8521                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8522                    .await
 8523            })
 8524        } else if let Some(local) = self.as_local() {
 8525            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8526                seed.worktree_id == symbol.source_worktree_id
 8527                    && state.id == symbol.source_language_server_id
 8528                    && symbol.language_server_name == seed.name
 8529            });
 8530            if !is_valid {
 8531                return Task::ready(Err(anyhow!(
 8532                    "language server for worktree and language not found"
 8533                )));
 8534            };
 8535
 8536            let symbol_abs_path = match &symbol.path {
 8537                SymbolLocation::InProject(project_path) => self
 8538                    .worktree_store
 8539                    .read(cx)
 8540                    .absolutize(&project_path, cx)
 8541                    .context("no such worktree"),
 8542                SymbolLocation::OutsideProject {
 8543                    abs_path,
 8544                    signature: _,
 8545                } => Ok(abs_path.to_path_buf()),
 8546            };
 8547            let symbol_abs_path = match symbol_abs_path {
 8548                Ok(abs_path) => abs_path,
 8549                Err(err) => return Task::ready(Err(err)),
 8550            };
 8551            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8552                uri
 8553            } else {
 8554                return Task::ready(Err(anyhow!("invalid symbol path")));
 8555            };
 8556
 8557            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8558        } else {
 8559            Task::ready(Err(anyhow!("no upstream client or local store")))
 8560        }
 8561    }
 8562
 8563    pub(crate) fn open_local_buffer_via_lsp(
 8564        &mut self,
 8565        abs_path: lsp::Uri,
 8566        language_server_id: LanguageServerId,
 8567        cx: &mut Context<Self>,
 8568    ) -> Task<Result<Entity<Buffer>>> {
 8569        cx.spawn(async move |lsp_store, cx| {
 8570            // Escape percent-encoded string.
 8571            let current_scheme = abs_path.scheme().to_owned();
 8572            // Uri is immutable, so we can't modify the scheme
 8573
 8574            let abs_path = abs_path
 8575                .to_file_path()
 8576                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8577            let p = abs_path.clone();
 8578            let yarn_worktree = lsp_store
 8579                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8580                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8581                        cx.spawn(async move |this, cx| {
 8582                            let t = this
 8583                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8584                                .ok()?;
 8585                            t.await
 8586                        })
 8587                    }),
 8588                    None => Task::ready(None),
 8589                })?
 8590                .await;
 8591            let (worktree_root_target, known_relative_path) =
 8592                if let Some((zip_root, relative_path)) = yarn_worktree {
 8593                    (zip_root, Some(relative_path))
 8594                } else {
 8595                    (Arc::<Path>::from(abs_path.as_path()), None)
 8596                };
 8597            let (worktree, relative_path) = if let Some(result) =
 8598                lsp_store.update(cx, |lsp_store, cx| {
 8599                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8600                        worktree_store.find_worktree(&worktree_root_target, cx)
 8601                    })
 8602                })? {
 8603                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8604                (result.0, relative_path)
 8605            } else {
 8606                let worktree = lsp_store
 8607                    .update(cx, |lsp_store, cx| {
 8608                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8609                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8610                        })
 8611                    })?
 8612                    .await?;
 8613                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8614                    lsp_store
 8615                        .update(cx, |lsp_store, cx| {
 8616                            if let Some(local) = lsp_store.as_local_mut() {
 8617                                local.register_language_server_for_invisible_worktree(
 8618                                    &worktree,
 8619                                    language_server_id,
 8620                                    cx,
 8621                                )
 8622                            }
 8623                        })
 8624                        .ok();
 8625                }
 8626                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8627                let relative_path = if let Some(known_path) = known_relative_path {
 8628                    known_path
 8629                } else {
 8630                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8631                        .into_arc()
 8632                };
 8633                (worktree, relative_path)
 8634            };
 8635            let project_path = ProjectPath {
 8636                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8637                path: relative_path,
 8638            };
 8639            lsp_store
 8640                .update(cx, |lsp_store, cx| {
 8641                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8642                        buffer_store.open_buffer(project_path, cx)
 8643                    })
 8644                })?
 8645                .await
 8646        })
 8647    }
 8648
 8649    fn request_multiple_lsp_locally<P, R>(
 8650        &mut self,
 8651        buffer: &Entity<Buffer>,
 8652        position: Option<P>,
 8653        request: R,
 8654        cx: &mut Context<Self>,
 8655    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8656    where
 8657        P: ToOffset,
 8658        R: LspCommand + Clone,
 8659        <R::LspRequest as lsp::request::Request>::Result: Send,
 8660        <R::LspRequest as lsp::request::Request>::Params: Send,
 8661    {
 8662        let Some(local) = self.as_local() else {
 8663            return Task::ready(Vec::new());
 8664        };
 8665
 8666        let snapshot = buffer.read(cx).snapshot();
 8667        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8668
 8669        let server_ids = buffer.update(cx, |buffer, cx| {
 8670            local
 8671                .language_servers_for_buffer(buffer, cx)
 8672                .filter(|(adapter, _)| {
 8673                    scope
 8674                        .as_ref()
 8675                        .map(|scope| scope.language_allowed(&adapter.name))
 8676                        .unwrap_or(true)
 8677                })
 8678                .map(|(_, server)| server.server_id())
 8679                .filter(|server_id| {
 8680                    self.as_local().is_none_or(|local| {
 8681                        local
 8682                            .buffers_opened_in_servers
 8683                            .get(&snapshot.remote_id())
 8684                            .is_some_and(|servers| servers.contains(server_id))
 8685                    })
 8686                })
 8687                .collect::<Vec<_>>()
 8688        });
 8689
 8690        let mut response_results = server_ids
 8691            .into_iter()
 8692            .map(|server_id| {
 8693                let task = self.request_lsp(
 8694                    buffer.clone(),
 8695                    LanguageServerToQuery::Other(server_id),
 8696                    request.clone(),
 8697                    cx,
 8698                );
 8699                async move { (server_id, task.await) }
 8700            })
 8701            .collect::<FuturesUnordered<_>>();
 8702
 8703        cx.background_spawn(async move {
 8704            let mut responses = Vec::with_capacity(response_results.len());
 8705            while let Some((server_id, response_result)) = response_results.next().await {
 8706                match response_result {
 8707                    Ok(response) => responses.push((server_id, response)),
 8708                    // rust-analyzer likes to error with this when its still loading up
 8709                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8710                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8711                }
 8712            }
 8713            responses
 8714        })
 8715    }
 8716
 8717    async fn handle_lsp_get_completions(
 8718        this: Entity<Self>,
 8719        envelope: TypedEnvelope<proto::GetCompletions>,
 8720        mut cx: AsyncApp,
 8721    ) -> Result<proto::GetCompletionsResponse> {
 8722        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8723
 8724        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8725        let buffer_handle = this.update(&mut cx, |this, cx| {
 8726            this.buffer_store.read(cx).get_existing(buffer_id)
 8727        })??;
 8728        let request = GetCompletions::from_proto(
 8729            envelope.payload,
 8730            this.clone(),
 8731            buffer_handle.clone(),
 8732            cx.clone(),
 8733        )
 8734        .await?;
 8735
 8736        let server_to_query = match request.server_id {
 8737            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8738            None => LanguageServerToQuery::FirstCapable,
 8739        };
 8740
 8741        let response = this
 8742            .update(&mut cx, |this, cx| {
 8743                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8744            })?
 8745            .await?;
 8746        this.update(&mut cx, |this, cx| {
 8747            Ok(GetCompletions::response_to_proto(
 8748                response,
 8749                this,
 8750                sender_id,
 8751                &buffer_handle.read(cx).version(),
 8752                cx,
 8753            ))
 8754        })?
 8755    }
 8756
 8757    async fn handle_lsp_command<T: LspCommand>(
 8758        this: Entity<Self>,
 8759        envelope: TypedEnvelope<T::ProtoRequest>,
 8760        mut cx: AsyncApp,
 8761    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8762    where
 8763        <T::LspRequest as lsp::request::Request>::Params: Send,
 8764        <T::LspRequest as lsp::request::Request>::Result: Send,
 8765    {
 8766        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8767        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8768        let buffer_handle = this.update(&mut cx, |this, cx| {
 8769            this.buffer_store.read(cx).get_existing(buffer_id)
 8770        })??;
 8771        let request = T::from_proto(
 8772            envelope.payload,
 8773            this.clone(),
 8774            buffer_handle.clone(),
 8775            cx.clone(),
 8776        )
 8777        .await?;
 8778        let response = this
 8779            .update(&mut cx, |this, cx| {
 8780                this.request_lsp(
 8781                    buffer_handle.clone(),
 8782                    LanguageServerToQuery::FirstCapable,
 8783                    request,
 8784                    cx,
 8785                )
 8786            })?
 8787            .await?;
 8788        this.update(&mut cx, |this, cx| {
 8789            Ok(T::response_to_proto(
 8790                response,
 8791                this,
 8792                sender_id,
 8793                &buffer_handle.read(cx).version(),
 8794                cx,
 8795            ))
 8796        })?
 8797    }
 8798
 8799    async fn handle_lsp_query(
 8800        lsp_store: Entity<Self>,
 8801        envelope: TypedEnvelope<proto::LspQuery>,
 8802        mut cx: AsyncApp,
 8803    ) -> Result<proto::Ack> {
 8804        use proto::lsp_query::Request;
 8805        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8806        let lsp_query = envelope.payload;
 8807        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8808        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8809        match lsp_query.request.context("invalid LSP query request")? {
 8810            Request::GetReferences(get_references) => {
 8811                let position = get_references.position.clone().and_then(deserialize_anchor);
 8812                Self::query_lsp_locally::<GetReferences>(
 8813                    lsp_store,
 8814                    server_id,
 8815                    sender_id,
 8816                    lsp_request_id,
 8817                    get_references,
 8818                    position,
 8819                    &mut cx,
 8820                )
 8821                .await?;
 8822            }
 8823            Request::GetDocumentColor(get_document_color) => {
 8824                Self::query_lsp_locally::<GetDocumentColor>(
 8825                    lsp_store,
 8826                    server_id,
 8827                    sender_id,
 8828                    lsp_request_id,
 8829                    get_document_color,
 8830                    None,
 8831                    &mut cx,
 8832                )
 8833                .await?;
 8834            }
 8835            Request::GetHover(get_hover) => {
 8836                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8837                Self::query_lsp_locally::<GetHover>(
 8838                    lsp_store,
 8839                    server_id,
 8840                    sender_id,
 8841                    lsp_request_id,
 8842                    get_hover,
 8843                    position,
 8844                    &mut cx,
 8845                )
 8846                .await?;
 8847            }
 8848            Request::GetCodeActions(get_code_actions) => {
 8849                Self::query_lsp_locally::<GetCodeActions>(
 8850                    lsp_store,
 8851                    server_id,
 8852                    sender_id,
 8853                    lsp_request_id,
 8854                    get_code_actions,
 8855                    None,
 8856                    &mut cx,
 8857                )
 8858                .await?;
 8859            }
 8860            Request::GetSignatureHelp(get_signature_help) => {
 8861                let position = get_signature_help
 8862                    .position
 8863                    .clone()
 8864                    .and_then(deserialize_anchor);
 8865                Self::query_lsp_locally::<GetSignatureHelp>(
 8866                    lsp_store,
 8867                    server_id,
 8868                    sender_id,
 8869                    lsp_request_id,
 8870                    get_signature_help,
 8871                    position,
 8872                    &mut cx,
 8873                )
 8874                .await?;
 8875            }
 8876            Request::GetCodeLens(get_code_lens) => {
 8877                Self::query_lsp_locally::<GetCodeLens>(
 8878                    lsp_store,
 8879                    server_id,
 8880                    sender_id,
 8881                    lsp_request_id,
 8882                    get_code_lens,
 8883                    None,
 8884                    &mut cx,
 8885                )
 8886                .await?;
 8887            }
 8888            Request::GetDefinition(get_definition) => {
 8889                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8890                Self::query_lsp_locally::<GetDefinitions>(
 8891                    lsp_store,
 8892                    server_id,
 8893                    sender_id,
 8894                    lsp_request_id,
 8895                    get_definition,
 8896                    position,
 8897                    &mut cx,
 8898                )
 8899                .await?;
 8900            }
 8901            Request::GetDeclaration(get_declaration) => {
 8902                let position = get_declaration
 8903                    .position
 8904                    .clone()
 8905                    .and_then(deserialize_anchor);
 8906                Self::query_lsp_locally::<GetDeclarations>(
 8907                    lsp_store,
 8908                    server_id,
 8909                    sender_id,
 8910                    lsp_request_id,
 8911                    get_declaration,
 8912                    position,
 8913                    &mut cx,
 8914                )
 8915                .await?;
 8916            }
 8917            Request::GetTypeDefinition(get_type_definition) => {
 8918                let position = get_type_definition
 8919                    .position
 8920                    .clone()
 8921                    .and_then(deserialize_anchor);
 8922                Self::query_lsp_locally::<GetTypeDefinitions>(
 8923                    lsp_store,
 8924                    server_id,
 8925                    sender_id,
 8926                    lsp_request_id,
 8927                    get_type_definition,
 8928                    position,
 8929                    &mut cx,
 8930                )
 8931                .await?;
 8932            }
 8933            Request::GetImplementation(get_implementation) => {
 8934                let position = get_implementation
 8935                    .position
 8936                    .clone()
 8937                    .and_then(deserialize_anchor);
 8938                Self::query_lsp_locally::<GetImplementations>(
 8939                    lsp_store,
 8940                    server_id,
 8941                    sender_id,
 8942                    lsp_request_id,
 8943                    get_implementation,
 8944                    position,
 8945                    &mut cx,
 8946                )
 8947                .await?;
 8948            }
 8949            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8950                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8951                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8952                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8953                    this.buffer_store.read(cx).get_existing(buffer_id)
 8954                })??;
 8955                buffer
 8956                    .update(&mut cx, |buffer, _| {
 8957                        buffer.wait_for_version(version.clone())
 8958                    })?
 8959                    .await?;
 8960                lsp_store.update(&mut cx, |lsp_store, cx| {
 8961                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8962                    let key = LspKey {
 8963                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8964                        server_queried: server_id,
 8965                    };
 8966                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8967                    ) {
 8968                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8969                            lsp_requests.clear();
 8970                        };
 8971                    }
 8972
 8973                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8974                    existing_queries.insert(
 8975                        lsp_request_id,
 8976                        cx.spawn(async move |lsp_store, cx| {
 8977                            let diagnostics_pull = lsp_store
 8978                                .update(cx, |lsp_store, cx| {
 8979                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8980                                })
 8981                                .ok();
 8982                            if let Some(diagnostics_pull) = diagnostics_pull {
 8983                                match diagnostics_pull.await {
 8984                                    Ok(()) => {}
 8985                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8986                                };
 8987                            }
 8988                        }),
 8989                    );
 8990                })?;
 8991            }
 8992            Request::InlayHints(inlay_hints) => {
 8993                let query_start = inlay_hints
 8994                    .start
 8995                    .clone()
 8996                    .and_then(deserialize_anchor)
 8997                    .context("invalid inlay hints range start")?;
 8998                let query_end = inlay_hints
 8999                    .end
 9000                    .clone()
 9001                    .and_then(deserialize_anchor)
 9002                    .context("invalid inlay hints range end")?;
 9003                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9004                    &lsp_store,
 9005                    server_id,
 9006                    lsp_request_id,
 9007                    &inlay_hints,
 9008                    query_start..query_end,
 9009                    &mut cx,
 9010                )
 9011                .await
 9012                .context("preparing inlay hints request")?;
 9013                Self::query_lsp_locally::<InlayHints>(
 9014                    lsp_store,
 9015                    server_id,
 9016                    sender_id,
 9017                    lsp_request_id,
 9018                    inlay_hints,
 9019                    None,
 9020                    &mut cx,
 9021                )
 9022                .await
 9023                .context("querying for inlay hints")?
 9024            }
 9025        }
 9026        Ok(proto::Ack {})
 9027    }
 9028
 9029    async fn handle_lsp_query_response(
 9030        lsp_store: Entity<Self>,
 9031        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9032        cx: AsyncApp,
 9033    ) -> Result<()> {
 9034        lsp_store.read_with(&cx, |lsp_store, _| {
 9035            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9036                upstream_client.handle_lsp_response(envelope.clone());
 9037            }
 9038        })?;
 9039        Ok(())
 9040    }
 9041
 9042    async fn handle_apply_code_action(
 9043        this: Entity<Self>,
 9044        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9045        mut cx: AsyncApp,
 9046    ) -> Result<proto::ApplyCodeActionResponse> {
 9047        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9048        let action =
 9049            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9050        let apply_code_action = this.update(&mut cx, |this, cx| {
 9051            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9052            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9053            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9054        })??;
 9055
 9056        let project_transaction = apply_code_action.await?;
 9057        let project_transaction = this.update(&mut cx, |this, cx| {
 9058            this.buffer_store.update(cx, |buffer_store, cx| {
 9059                buffer_store.serialize_project_transaction_for_peer(
 9060                    project_transaction,
 9061                    sender_id,
 9062                    cx,
 9063                )
 9064            })
 9065        })?;
 9066        Ok(proto::ApplyCodeActionResponse {
 9067            transaction: Some(project_transaction),
 9068        })
 9069    }
 9070
 9071    async fn handle_register_buffer_with_language_servers(
 9072        this: Entity<Self>,
 9073        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9074        mut cx: AsyncApp,
 9075    ) -> Result<proto::Ack> {
 9076        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9077        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9078        this.update(&mut cx, |this, cx| {
 9079            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9080                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9081                    project_id: upstream_project_id,
 9082                    buffer_id: buffer_id.to_proto(),
 9083                    only_servers: envelope.payload.only_servers,
 9084                });
 9085            }
 9086
 9087            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9088                anyhow::bail!("buffer is not open");
 9089            };
 9090
 9091            let handle = this.register_buffer_with_language_servers(
 9092                &buffer,
 9093                envelope
 9094                    .payload
 9095                    .only_servers
 9096                    .into_iter()
 9097                    .filter_map(|selector| {
 9098                        Some(match selector.selector? {
 9099                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9100                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9101                            }
 9102                            proto::language_server_selector::Selector::Name(name) => {
 9103                                LanguageServerSelector::Name(LanguageServerName(
 9104                                    SharedString::from(name),
 9105                                ))
 9106                            }
 9107                        })
 9108                    })
 9109                    .collect(),
 9110                false,
 9111                cx,
 9112            );
 9113            this.buffer_store().update(cx, |buffer_store, _| {
 9114                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9115            });
 9116
 9117            Ok(())
 9118        })??;
 9119        Ok(proto::Ack {})
 9120    }
 9121
 9122    async fn handle_rename_project_entry(
 9123        this: Entity<Self>,
 9124        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9125        mut cx: AsyncApp,
 9126    ) -> Result<proto::ProjectEntryResponse> {
 9127        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9128        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9129        let new_path =
 9130            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9131
 9132        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9133            .update(&mut cx, |this, cx| {
 9134                let (worktree, entry) = this
 9135                    .worktree_store
 9136                    .read(cx)
 9137                    .worktree_and_entry_for_id(entry_id, cx)?;
 9138                let new_worktree = this
 9139                    .worktree_store
 9140                    .read(cx)
 9141                    .worktree_for_id(new_worktree_id, cx)?;
 9142                Some((
 9143                    this.worktree_store.clone(),
 9144                    worktree,
 9145                    new_worktree,
 9146                    entry.clone(),
 9147                ))
 9148            })?
 9149            .context("worktree not found")?;
 9150        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9151            (worktree.absolutize(&old_entry.path), worktree.id())
 9152        })?;
 9153        let new_abs_path =
 9154            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 9155
 9156        let _transaction = Self::will_rename_entry(
 9157            this.downgrade(),
 9158            old_worktree_id,
 9159            &old_abs_path,
 9160            &new_abs_path,
 9161            old_entry.is_dir(),
 9162            cx.clone(),
 9163        )
 9164        .await;
 9165        let response = WorktreeStore::handle_rename_project_entry(
 9166            worktree_store,
 9167            envelope.payload,
 9168            cx.clone(),
 9169        )
 9170        .await;
 9171        this.read_with(&cx, |this, _| {
 9172            this.did_rename_entry(
 9173                old_worktree_id,
 9174                &old_abs_path,
 9175                &new_abs_path,
 9176                old_entry.is_dir(),
 9177            );
 9178        })
 9179        .ok();
 9180        response
 9181    }
 9182
 9183    async fn handle_update_diagnostic_summary(
 9184        this: Entity<Self>,
 9185        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9186        mut cx: AsyncApp,
 9187    ) -> Result<()> {
 9188        this.update(&mut cx, |lsp_store, cx| {
 9189            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9190            let mut updated_diagnostics_paths = HashMap::default();
 9191            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9192            for message_summary in envelope
 9193                .payload
 9194                .summary
 9195                .into_iter()
 9196                .chain(envelope.payload.more_summaries)
 9197            {
 9198                let project_path = ProjectPath {
 9199                    worktree_id,
 9200                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9201                };
 9202                let path = project_path.path.clone();
 9203                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9204                let summary = DiagnosticSummary {
 9205                    error_count: message_summary.error_count as usize,
 9206                    warning_count: message_summary.warning_count as usize,
 9207                };
 9208
 9209                if summary.is_empty() {
 9210                    if let Some(worktree_summaries) =
 9211                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9212                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9213                    {
 9214                        summaries.remove(&server_id);
 9215                        if summaries.is_empty() {
 9216                            worktree_summaries.remove(&path);
 9217                        }
 9218                    }
 9219                } else {
 9220                    lsp_store
 9221                        .diagnostic_summaries
 9222                        .entry(worktree_id)
 9223                        .or_default()
 9224                        .entry(path)
 9225                        .or_default()
 9226                        .insert(server_id, summary);
 9227                }
 9228
 9229                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9230                    match &mut diagnostics_summary {
 9231                        Some(diagnostics_summary) => {
 9232                            diagnostics_summary
 9233                                .more_summaries
 9234                                .push(proto::DiagnosticSummary {
 9235                                    path: project_path.path.as_ref().to_proto(),
 9236                                    language_server_id: server_id.0 as u64,
 9237                                    error_count: summary.error_count as u32,
 9238                                    warning_count: summary.warning_count as u32,
 9239                                })
 9240                        }
 9241                        None => {
 9242                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9243                                project_id: *project_id,
 9244                                worktree_id: worktree_id.to_proto(),
 9245                                summary: Some(proto::DiagnosticSummary {
 9246                                    path: project_path.path.as_ref().to_proto(),
 9247                                    language_server_id: server_id.0 as u64,
 9248                                    error_count: summary.error_count as u32,
 9249                                    warning_count: summary.warning_count as u32,
 9250                                }),
 9251                                more_summaries: Vec::new(),
 9252                            })
 9253                        }
 9254                    }
 9255                }
 9256                updated_diagnostics_paths
 9257                    .entry(server_id)
 9258                    .or_insert_with(Vec::new)
 9259                    .push(project_path);
 9260            }
 9261
 9262            if let Some((diagnostics_summary, (downstream_client, _))) =
 9263                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9264            {
 9265                downstream_client.send(diagnostics_summary).log_err();
 9266            }
 9267            for (server_id, paths) in updated_diagnostics_paths {
 9268                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9269            }
 9270            Ok(())
 9271        })?
 9272    }
 9273
 9274    async fn handle_start_language_server(
 9275        lsp_store: Entity<Self>,
 9276        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9277        mut cx: AsyncApp,
 9278    ) -> Result<()> {
 9279        let server = envelope.payload.server.context("invalid server")?;
 9280        let server_capabilities =
 9281            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9282                .with_context(|| {
 9283                    format!(
 9284                        "incorrect server capabilities {}",
 9285                        envelope.payload.capabilities
 9286                    )
 9287                })?;
 9288        lsp_store.update(&mut cx, |lsp_store, cx| {
 9289            let server_id = LanguageServerId(server.id as usize);
 9290            let server_name = LanguageServerName::from_proto(server.name.clone());
 9291            lsp_store
 9292                .lsp_server_capabilities
 9293                .insert(server_id, server_capabilities);
 9294            lsp_store.language_server_statuses.insert(
 9295                server_id,
 9296                LanguageServerStatus {
 9297                    name: server_name.clone(),
 9298                    pending_work: Default::default(),
 9299                    has_pending_diagnostic_updates: false,
 9300                    progress_tokens: Default::default(),
 9301                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9302                    binary: None,
 9303                    configuration: None,
 9304                    workspace_folders: BTreeSet::new(),
 9305                },
 9306            );
 9307            cx.emit(LspStoreEvent::LanguageServerAdded(
 9308                server_id,
 9309                server_name,
 9310                server.worktree_id.map(WorktreeId::from_proto),
 9311            ));
 9312            cx.notify();
 9313        })?;
 9314        Ok(())
 9315    }
 9316
 9317    async fn handle_update_language_server(
 9318        lsp_store: Entity<Self>,
 9319        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9320        mut cx: AsyncApp,
 9321    ) -> Result<()> {
 9322        lsp_store.update(&mut cx, |lsp_store, cx| {
 9323            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9324
 9325            match envelope.payload.variant.context("invalid variant")? {
 9326                proto::update_language_server::Variant::WorkStart(payload) => {
 9327                    lsp_store.on_lsp_work_start(
 9328                        language_server_id,
 9329                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9330                            .context("invalid progress token value")?,
 9331                        LanguageServerProgress {
 9332                            title: payload.title,
 9333                            is_disk_based_diagnostics_progress: false,
 9334                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9335                            message: payload.message,
 9336                            percentage: payload.percentage.map(|p| p as usize),
 9337                            last_update_at: cx.background_executor().now(),
 9338                        },
 9339                        cx,
 9340                    );
 9341                }
 9342                proto::update_language_server::Variant::WorkProgress(payload) => {
 9343                    lsp_store.on_lsp_work_progress(
 9344                        language_server_id,
 9345                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9346                            .context("invalid progress token value")?,
 9347                        LanguageServerProgress {
 9348                            title: None,
 9349                            is_disk_based_diagnostics_progress: false,
 9350                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9351                            message: payload.message,
 9352                            percentage: payload.percentage.map(|p| p as usize),
 9353                            last_update_at: cx.background_executor().now(),
 9354                        },
 9355                        cx,
 9356                    );
 9357                }
 9358
 9359                proto::update_language_server::Variant::WorkEnd(payload) => {
 9360                    lsp_store.on_lsp_work_end(
 9361                        language_server_id,
 9362                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9363                            .context("invalid progress token value")?,
 9364                        cx,
 9365                    );
 9366                }
 9367
 9368                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9369                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9370                }
 9371
 9372                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9373                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9374                }
 9375
 9376                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9377                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9378                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9379                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9380                        language_server_id,
 9381                        name: envelope
 9382                            .payload
 9383                            .server_name
 9384                            .map(SharedString::new)
 9385                            .map(LanguageServerName),
 9386                        message: non_lsp,
 9387                    });
 9388                }
 9389            }
 9390
 9391            Ok(())
 9392        })?
 9393    }
 9394
 9395    async fn handle_language_server_log(
 9396        this: Entity<Self>,
 9397        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9398        mut cx: AsyncApp,
 9399    ) -> Result<()> {
 9400        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9401        let log_type = envelope
 9402            .payload
 9403            .log_type
 9404            .map(LanguageServerLogType::from_proto)
 9405            .context("invalid language server log type")?;
 9406
 9407        let message = envelope.payload.message;
 9408
 9409        this.update(&mut cx, |_, cx| {
 9410            cx.emit(LspStoreEvent::LanguageServerLog(
 9411                language_server_id,
 9412                log_type,
 9413                message,
 9414            ));
 9415        })
 9416    }
 9417
 9418    async fn handle_lsp_ext_cancel_flycheck(
 9419        lsp_store: Entity<Self>,
 9420        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9421        cx: AsyncApp,
 9422    ) -> Result<proto::Ack> {
 9423        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9424        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9425            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9426                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9427            } else {
 9428                None
 9429            }
 9430        })?;
 9431        if let Some(task) = task {
 9432            task.context("handling lsp ext cancel flycheck")?;
 9433        }
 9434
 9435        Ok(proto::Ack {})
 9436    }
 9437
 9438    async fn handle_lsp_ext_run_flycheck(
 9439        lsp_store: Entity<Self>,
 9440        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9441        mut cx: AsyncApp,
 9442    ) -> Result<proto::Ack> {
 9443        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9444        lsp_store.update(&mut cx, |lsp_store, cx| {
 9445            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9446                let text_document = if envelope.payload.current_file_only {
 9447                    let buffer_id = envelope
 9448                        .payload
 9449                        .buffer_id
 9450                        .map(|id| BufferId::new(id))
 9451                        .transpose()?;
 9452                    buffer_id
 9453                        .and_then(|buffer_id| {
 9454                            lsp_store
 9455                                .buffer_store()
 9456                                .read(cx)
 9457                                .get(buffer_id)
 9458                                .and_then(|buffer| {
 9459                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9460                                })
 9461                                .map(|path| make_text_document_identifier(&path))
 9462                        })
 9463                        .transpose()?
 9464                } else {
 9465                    None
 9466                };
 9467                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9468                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9469                )?;
 9470            }
 9471            anyhow::Ok(())
 9472        })??;
 9473
 9474        Ok(proto::Ack {})
 9475    }
 9476
 9477    async fn handle_lsp_ext_clear_flycheck(
 9478        lsp_store: Entity<Self>,
 9479        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9480        cx: AsyncApp,
 9481    ) -> Result<proto::Ack> {
 9482        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9483        lsp_store
 9484            .read_with(&cx, |lsp_store, _| {
 9485                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9486                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9487                } else {
 9488                    None
 9489                }
 9490            })
 9491            .context("handling lsp ext clear flycheck")?;
 9492
 9493        Ok(proto::Ack {})
 9494    }
 9495
 9496    pub fn disk_based_diagnostics_started(
 9497        &mut self,
 9498        language_server_id: LanguageServerId,
 9499        cx: &mut Context<Self>,
 9500    ) {
 9501        if let Some(language_server_status) =
 9502            self.language_server_statuses.get_mut(&language_server_id)
 9503        {
 9504            language_server_status.has_pending_diagnostic_updates = true;
 9505        }
 9506
 9507        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9508        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9509            language_server_id,
 9510            name: self
 9511                .language_server_adapter_for_id(language_server_id)
 9512                .map(|adapter| adapter.name()),
 9513            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9514                Default::default(),
 9515            ),
 9516        })
 9517    }
 9518
 9519    pub fn disk_based_diagnostics_finished(
 9520        &mut self,
 9521        language_server_id: LanguageServerId,
 9522        cx: &mut Context<Self>,
 9523    ) {
 9524        if let Some(language_server_status) =
 9525            self.language_server_statuses.get_mut(&language_server_id)
 9526        {
 9527            language_server_status.has_pending_diagnostic_updates = false;
 9528        }
 9529
 9530        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9531        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9532            language_server_id,
 9533            name: self
 9534                .language_server_adapter_for_id(language_server_id)
 9535                .map(|adapter| adapter.name()),
 9536            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9537                Default::default(),
 9538            ),
 9539        })
 9540    }
 9541
 9542    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9543    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9544    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9545    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9546    // the language server might take some time to publish diagnostics.
 9547    fn simulate_disk_based_diagnostics_events_if_needed(
 9548        &mut self,
 9549        language_server_id: LanguageServerId,
 9550        cx: &mut Context<Self>,
 9551    ) {
 9552        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9553
 9554        let Some(LanguageServerState::Running {
 9555            simulate_disk_based_diagnostics_completion,
 9556            adapter,
 9557            ..
 9558        }) = self
 9559            .as_local_mut()
 9560            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9561        else {
 9562            return;
 9563        };
 9564
 9565        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9566            return;
 9567        }
 9568
 9569        let prev_task =
 9570            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9571                cx.background_executor()
 9572                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9573                    .await;
 9574
 9575                this.update(cx, |this, cx| {
 9576                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9577
 9578                    if let Some(LanguageServerState::Running {
 9579                        simulate_disk_based_diagnostics_completion,
 9580                        ..
 9581                    }) = this.as_local_mut().and_then(|local_store| {
 9582                        local_store.language_servers.get_mut(&language_server_id)
 9583                    }) {
 9584                        *simulate_disk_based_diagnostics_completion = None;
 9585                    }
 9586                })
 9587                .ok();
 9588            }));
 9589
 9590        if prev_task.is_none() {
 9591            self.disk_based_diagnostics_started(language_server_id, cx);
 9592        }
 9593    }
 9594
 9595    pub fn language_server_statuses(
 9596        &self,
 9597    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9598        self.language_server_statuses
 9599            .iter()
 9600            .map(|(key, value)| (*key, value))
 9601    }
 9602
 9603    pub(super) fn did_rename_entry(
 9604        &self,
 9605        worktree_id: WorktreeId,
 9606        old_path: &Path,
 9607        new_path: &Path,
 9608        is_dir: bool,
 9609    ) {
 9610        maybe!({
 9611            let local_store = self.as_local()?;
 9612
 9613            let old_uri = lsp::Uri::from_file_path(old_path)
 9614                .ok()
 9615                .map(|uri| uri.to_string())?;
 9616            let new_uri = lsp::Uri::from_file_path(new_path)
 9617                .ok()
 9618                .map(|uri| uri.to_string())?;
 9619
 9620            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9621                let Some(filter) = local_store
 9622                    .language_server_paths_watched_for_rename
 9623                    .get(&language_server.server_id())
 9624                else {
 9625                    continue;
 9626                };
 9627
 9628                if filter.should_send_did_rename(&old_uri, is_dir) {
 9629                    language_server
 9630                        .notify::<DidRenameFiles>(RenameFilesParams {
 9631                            files: vec![FileRename {
 9632                                old_uri: old_uri.clone(),
 9633                                new_uri: new_uri.clone(),
 9634                            }],
 9635                        })
 9636                        .ok();
 9637                }
 9638            }
 9639            Some(())
 9640        });
 9641    }
 9642
 9643    pub(super) fn will_rename_entry(
 9644        this: WeakEntity<Self>,
 9645        worktree_id: WorktreeId,
 9646        old_path: &Path,
 9647        new_path: &Path,
 9648        is_dir: bool,
 9649        cx: AsyncApp,
 9650    ) -> Task<ProjectTransaction> {
 9651        let old_uri = lsp::Uri::from_file_path(old_path)
 9652            .ok()
 9653            .map(|uri| uri.to_string());
 9654        let new_uri = lsp::Uri::from_file_path(new_path)
 9655            .ok()
 9656            .map(|uri| uri.to_string());
 9657        cx.spawn(async move |cx| {
 9658            let mut tasks = vec![];
 9659            this.update(cx, |this, cx| {
 9660                let local_store = this.as_local()?;
 9661                let old_uri = old_uri?;
 9662                let new_uri = new_uri?;
 9663                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9664                    let Some(filter) = local_store
 9665                        .language_server_paths_watched_for_rename
 9666                        .get(&language_server.server_id())
 9667                    else {
 9668                        continue;
 9669                    };
 9670
 9671                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9672                        let apply_edit = cx.spawn({
 9673                            let old_uri = old_uri.clone();
 9674                            let new_uri = new_uri.clone();
 9675                            let language_server = language_server.clone();
 9676                            async move |this, cx| {
 9677                                let edit = language_server
 9678                                    .request::<WillRenameFiles>(RenameFilesParams {
 9679                                        files: vec![FileRename { old_uri, new_uri }],
 9680                                    })
 9681                                    .await
 9682                                    .into_response()
 9683                                    .context("will rename files")
 9684                                    .log_err()
 9685                                    .flatten()?;
 9686
 9687                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9688                                    this.upgrade()?,
 9689                                    edit,
 9690                                    false,
 9691                                    language_server.clone(),
 9692                                    cx,
 9693                                )
 9694                                .await
 9695                                .ok()?;
 9696                                Some(transaction)
 9697                            }
 9698                        });
 9699                        tasks.push(apply_edit);
 9700                    }
 9701                }
 9702                Some(())
 9703            })
 9704            .ok()
 9705            .flatten();
 9706            let mut merged_transaction = ProjectTransaction::default();
 9707            for task in tasks {
 9708                // Await on tasks sequentially so that the order of application of edits is deterministic
 9709                // (at least with regards to the order of registration of language servers)
 9710                if let Some(transaction) = task.await {
 9711                    for (buffer, buffer_transaction) in transaction.0 {
 9712                        merged_transaction.0.insert(buffer, buffer_transaction);
 9713                    }
 9714                }
 9715            }
 9716            merged_transaction
 9717        })
 9718    }
 9719
 9720    fn lsp_notify_abs_paths_changed(
 9721        &mut self,
 9722        server_id: LanguageServerId,
 9723        changes: Vec<PathEvent>,
 9724    ) {
 9725        maybe!({
 9726            let server = self.language_server_for_id(server_id)?;
 9727            let changes = changes
 9728                .into_iter()
 9729                .filter_map(|event| {
 9730                    let typ = match event.kind? {
 9731                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9732                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9733                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9734                    };
 9735                    Some(lsp::FileEvent {
 9736                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9737                        typ,
 9738                    })
 9739                })
 9740                .collect::<Vec<_>>();
 9741            if !changes.is_empty() {
 9742                server
 9743                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9744                        lsp::DidChangeWatchedFilesParams { changes },
 9745                    )
 9746                    .ok();
 9747            }
 9748            Some(())
 9749        });
 9750    }
 9751
 9752    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9753        self.as_local()?.language_server_for_id(id)
 9754    }
 9755
 9756    fn on_lsp_progress(
 9757        &mut self,
 9758        progress_params: lsp::ProgressParams,
 9759        language_server_id: LanguageServerId,
 9760        disk_based_diagnostics_progress_token: Option<String>,
 9761        cx: &mut Context<Self>,
 9762    ) {
 9763        match progress_params.value {
 9764            lsp::ProgressParamsValue::WorkDone(progress) => {
 9765                self.handle_work_done_progress(
 9766                    progress,
 9767                    language_server_id,
 9768                    disk_based_diagnostics_progress_token,
 9769                    ProgressToken::from_lsp(progress_params.token),
 9770                    cx,
 9771                );
 9772            }
 9773            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9774                let registration_id = match progress_params.token {
 9775                    lsp::NumberOrString::Number(_) => None,
 9776                    lsp::NumberOrString::String(token) => token
 9777                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9778                        .map(|(_, id)| id.to_owned()),
 9779                };
 9780                if let Some(LanguageServerState::Running {
 9781                    workspace_diagnostics_refresh_tasks,
 9782                    ..
 9783                }) = self
 9784                    .as_local_mut()
 9785                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9786                    && let Some(workspace_diagnostics) =
 9787                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9788                {
 9789                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9790                    self.apply_workspace_diagnostic_report(
 9791                        language_server_id,
 9792                        report,
 9793                        registration_id.map(SharedString::from),
 9794                        cx,
 9795                    )
 9796                }
 9797            }
 9798        }
 9799    }
 9800
 9801    fn handle_work_done_progress(
 9802        &mut self,
 9803        progress: lsp::WorkDoneProgress,
 9804        language_server_id: LanguageServerId,
 9805        disk_based_diagnostics_progress_token: Option<String>,
 9806        token: ProgressToken,
 9807        cx: &mut Context<Self>,
 9808    ) {
 9809        let language_server_status =
 9810            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9811                status
 9812            } else {
 9813                return;
 9814            };
 9815
 9816        if !language_server_status.progress_tokens.contains(&token) {
 9817            return;
 9818        }
 9819
 9820        let is_disk_based_diagnostics_progress =
 9821            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9822                (&disk_based_diagnostics_progress_token, &token)
 9823            {
 9824                token.starts_with(disk_based_token)
 9825            } else {
 9826                false
 9827            };
 9828
 9829        match progress {
 9830            lsp::WorkDoneProgress::Begin(report) => {
 9831                if is_disk_based_diagnostics_progress {
 9832                    self.disk_based_diagnostics_started(language_server_id, cx);
 9833                }
 9834                self.on_lsp_work_start(
 9835                    language_server_id,
 9836                    token.clone(),
 9837                    LanguageServerProgress {
 9838                        title: Some(report.title),
 9839                        is_disk_based_diagnostics_progress,
 9840                        is_cancellable: report.cancellable.unwrap_or(false),
 9841                        message: report.message.clone(),
 9842                        percentage: report.percentage.map(|p| p as usize),
 9843                        last_update_at: cx.background_executor().now(),
 9844                    },
 9845                    cx,
 9846                );
 9847            }
 9848            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9849                language_server_id,
 9850                token,
 9851                LanguageServerProgress {
 9852                    title: None,
 9853                    is_disk_based_diagnostics_progress,
 9854                    is_cancellable: report.cancellable.unwrap_or(false),
 9855                    message: report.message,
 9856                    percentage: report.percentage.map(|p| p as usize),
 9857                    last_update_at: cx.background_executor().now(),
 9858                },
 9859                cx,
 9860            ),
 9861            lsp::WorkDoneProgress::End(_) => {
 9862                language_server_status.progress_tokens.remove(&token);
 9863                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9864                if is_disk_based_diagnostics_progress {
 9865                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9866                }
 9867            }
 9868        }
 9869    }
 9870
 9871    fn on_lsp_work_start(
 9872        &mut self,
 9873        language_server_id: LanguageServerId,
 9874        token: ProgressToken,
 9875        progress: LanguageServerProgress,
 9876        cx: &mut Context<Self>,
 9877    ) {
 9878        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9879            status.pending_work.insert(token.clone(), progress.clone());
 9880            cx.notify();
 9881        }
 9882        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9883            language_server_id,
 9884            name: self
 9885                .language_server_adapter_for_id(language_server_id)
 9886                .map(|adapter| adapter.name()),
 9887            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9888                token: Some(token.to_proto()),
 9889                title: progress.title,
 9890                message: progress.message,
 9891                percentage: progress.percentage.map(|p| p as u32),
 9892                is_cancellable: Some(progress.is_cancellable),
 9893            }),
 9894        })
 9895    }
 9896
 9897    fn on_lsp_work_progress(
 9898        &mut self,
 9899        language_server_id: LanguageServerId,
 9900        token: ProgressToken,
 9901        progress: LanguageServerProgress,
 9902        cx: &mut Context<Self>,
 9903    ) {
 9904        let mut did_update = false;
 9905        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9906            match status.pending_work.entry(token.clone()) {
 9907                btree_map::Entry::Vacant(entry) => {
 9908                    entry.insert(progress.clone());
 9909                    did_update = true;
 9910                }
 9911                btree_map::Entry::Occupied(mut entry) => {
 9912                    let entry = entry.get_mut();
 9913                    if (progress.last_update_at - entry.last_update_at)
 9914                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9915                    {
 9916                        entry.last_update_at = progress.last_update_at;
 9917                        if progress.message.is_some() {
 9918                            entry.message = progress.message.clone();
 9919                        }
 9920                        if progress.percentage.is_some() {
 9921                            entry.percentage = progress.percentage;
 9922                        }
 9923                        if progress.is_cancellable != entry.is_cancellable {
 9924                            entry.is_cancellable = progress.is_cancellable;
 9925                        }
 9926                        did_update = true;
 9927                    }
 9928                }
 9929            }
 9930        }
 9931
 9932        if did_update {
 9933            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9934                language_server_id,
 9935                name: self
 9936                    .language_server_adapter_for_id(language_server_id)
 9937                    .map(|adapter| adapter.name()),
 9938                message: proto::update_language_server::Variant::WorkProgress(
 9939                    proto::LspWorkProgress {
 9940                        token: Some(token.to_proto()),
 9941                        message: progress.message,
 9942                        percentage: progress.percentage.map(|p| p as u32),
 9943                        is_cancellable: Some(progress.is_cancellable),
 9944                    },
 9945                ),
 9946            })
 9947        }
 9948    }
 9949
 9950    fn on_lsp_work_end(
 9951        &mut self,
 9952        language_server_id: LanguageServerId,
 9953        token: ProgressToken,
 9954        cx: &mut Context<Self>,
 9955    ) {
 9956        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9957            if let Some(work) = status.pending_work.remove(&token)
 9958                && !work.is_disk_based_diagnostics_progress
 9959            {
 9960                cx.emit(LspStoreEvent::RefreshInlayHints {
 9961                    server_id: language_server_id,
 9962                    request_id: None,
 9963                });
 9964            }
 9965            cx.notify();
 9966        }
 9967
 9968        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9969            language_server_id,
 9970            name: self
 9971                .language_server_adapter_for_id(language_server_id)
 9972                .map(|adapter| adapter.name()),
 9973            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9974                token: Some(token.to_proto()),
 9975            }),
 9976        })
 9977    }
 9978
 9979    pub async fn handle_resolve_completion_documentation(
 9980        this: Entity<Self>,
 9981        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9982        mut cx: AsyncApp,
 9983    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9984        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9985
 9986        let completion = this
 9987            .read_with(&cx, |this, cx| {
 9988                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9989                let server = this
 9990                    .language_server_for_id(id)
 9991                    .with_context(|| format!("No language server {id}"))?;
 9992
 9993                anyhow::Ok(cx.background_spawn(async move {
 9994                    let can_resolve = server
 9995                        .capabilities()
 9996                        .completion_provider
 9997                        .as_ref()
 9998                        .and_then(|options| options.resolve_provider)
 9999                        .unwrap_or(false);
10000                    if can_resolve {
10001                        server
10002                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10003                            .await
10004                            .into_response()
10005                            .context("resolve completion item")
10006                    } else {
10007                        anyhow::Ok(lsp_completion)
10008                    }
10009                }))
10010            })??
10011            .await?;
10012
10013        let mut documentation_is_markdown = false;
10014        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10015        let documentation = match completion.documentation {
10016            Some(lsp::Documentation::String(text)) => text,
10017
10018            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10019                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10020                value
10021            }
10022
10023            _ => String::new(),
10024        };
10025
10026        // If we have a new buffer_id, that means we're talking to a new client
10027        // and want to check for new text_edits in the completion too.
10028        let mut old_replace_start = None;
10029        let mut old_replace_end = None;
10030        let mut old_insert_start = None;
10031        let mut old_insert_end = None;
10032        let mut new_text = String::default();
10033        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10034            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10035                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10036                anyhow::Ok(buffer.read(cx).snapshot())
10037            })??;
10038
10039            if let Some(text_edit) = completion.text_edit.as_ref() {
10040                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10041
10042                if let Some(mut edit) = edit {
10043                    LineEnding::normalize(&mut edit.new_text);
10044
10045                    new_text = edit.new_text;
10046                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10047                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10048                    if let Some(insert_range) = edit.insert_range {
10049                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10050                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10051                    }
10052                }
10053            }
10054        }
10055
10056        Ok(proto::ResolveCompletionDocumentationResponse {
10057            documentation,
10058            documentation_is_markdown,
10059            old_replace_start,
10060            old_replace_end,
10061            new_text,
10062            lsp_completion,
10063            old_insert_start,
10064            old_insert_end,
10065        })
10066    }
10067
10068    async fn handle_on_type_formatting(
10069        this: Entity<Self>,
10070        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10071        mut cx: AsyncApp,
10072    ) -> Result<proto::OnTypeFormattingResponse> {
10073        let on_type_formatting = this.update(&mut cx, |this, cx| {
10074            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10075            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10076            let position = envelope
10077                .payload
10078                .position
10079                .and_then(deserialize_anchor)
10080                .context("invalid position")?;
10081            anyhow::Ok(this.apply_on_type_formatting(
10082                buffer,
10083                position,
10084                envelope.payload.trigger.clone(),
10085                cx,
10086            ))
10087        })??;
10088
10089        let transaction = on_type_formatting
10090            .await?
10091            .as_ref()
10092            .map(language::proto::serialize_transaction);
10093        Ok(proto::OnTypeFormattingResponse { transaction })
10094    }
10095
10096    async fn handle_refresh_inlay_hints(
10097        lsp_store: Entity<Self>,
10098        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10099        mut cx: AsyncApp,
10100    ) -> Result<proto::Ack> {
10101        lsp_store.update(&mut cx, |_, cx| {
10102            cx.emit(LspStoreEvent::RefreshInlayHints {
10103                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10104                request_id: envelope.payload.request_id.map(|id| id as usize),
10105            });
10106        })?;
10107        Ok(proto::Ack {})
10108    }
10109
10110    async fn handle_pull_workspace_diagnostics(
10111        lsp_store: Entity<Self>,
10112        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10113        mut cx: AsyncApp,
10114    ) -> Result<proto::Ack> {
10115        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10116        lsp_store.update(&mut cx, |lsp_store, _| {
10117            lsp_store.pull_workspace_diagnostics(server_id);
10118        })?;
10119        Ok(proto::Ack {})
10120    }
10121
10122    async fn handle_get_color_presentation(
10123        lsp_store: Entity<Self>,
10124        envelope: TypedEnvelope<proto::GetColorPresentation>,
10125        mut cx: AsyncApp,
10126    ) -> Result<proto::GetColorPresentationResponse> {
10127        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10128        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10129            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10130        })??;
10131
10132        let color = envelope
10133            .payload
10134            .color
10135            .context("invalid color resolve request")?;
10136        let start = color
10137            .lsp_range_start
10138            .context("invalid color resolve request")?;
10139        let end = color
10140            .lsp_range_end
10141            .context("invalid color resolve request")?;
10142
10143        let color = DocumentColor {
10144            lsp_range: lsp::Range {
10145                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10146                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10147            },
10148            color: lsp::Color {
10149                red: color.red,
10150                green: color.green,
10151                blue: color.blue,
10152                alpha: color.alpha,
10153            },
10154            resolved: false,
10155            color_presentations: Vec::new(),
10156        };
10157        let resolved_color = lsp_store
10158            .update(&mut cx, |lsp_store, cx| {
10159                lsp_store.resolve_color_presentation(
10160                    color,
10161                    buffer.clone(),
10162                    LanguageServerId(envelope.payload.server_id as usize),
10163                    cx,
10164                )
10165            })?
10166            .await
10167            .context("resolving color presentation")?;
10168
10169        Ok(proto::GetColorPresentationResponse {
10170            presentations: resolved_color
10171                .color_presentations
10172                .into_iter()
10173                .map(|presentation| proto::ColorPresentation {
10174                    label: presentation.label.to_string(),
10175                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10176                    additional_text_edits: presentation
10177                        .additional_text_edits
10178                        .into_iter()
10179                        .map(serialize_lsp_edit)
10180                        .collect(),
10181                })
10182                .collect(),
10183        })
10184    }
10185
10186    async fn handle_resolve_inlay_hint(
10187        lsp_store: Entity<Self>,
10188        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10189        mut cx: AsyncApp,
10190    ) -> Result<proto::ResolveInlayHintResponse> {
10191        let proto_hint = envelope
10192            .payload
10193            .hint
10194            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10195        let hint = InlayHints::proto_to_project_hint(proto_hint)
10196            .context("resolved proto inlay hint conversion")?;
10197        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10198            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10199            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10200        })??;
10201        let response_hint = lsp_store
10202            .update(&mut cx, |lsp_store, cx| {
10203                lsp_store.resolve_inlay_hint(
10204                    hint,
10205                    buffer,
10206                    LanguageServerId(envelope.payload.language_server_id as usize),
10207                    cx,
10208                )
10209            })?
10210            .await
10211            .context("inlay hints fetch")?;
10212        Ok(proto::ResolveInlayHintResponse {
10213            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10214        })
10215    }
10216
10217    async fn handle_refresh_code_lens(
10218        this: Entity<Self>,
10219        _: TypedEnvelope<proto::RefreshCodeLens>,
10220        mut cx: AsyncApp,
10221    ) -> Result<proto::Ack> {
10222        this.update(&mut cx, |_, cx| {
10223            cx.emit(LspStoreEvent::RefreshCodeLens);
10224        })?;
10225        Ok(proto::Ack {})
10226    }
10227
10228    async fn handle_open_buffer_for_symbol(
10229        this: Entity<Self>,
10230        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10231        mut cx: AsyncApp,
10232    ) -> Result<proto::OpenBufferForSymbolResponse> {
10233        let peer_id = envelope.original_sender_id().unwrap_or_default();
10234        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10235        let symbol = Self::deserialize_symbol(symbol)?;
10236        this.read_with(&cx, |this, _| {
10237            if let SymbolLocation::OutsideProject {
10238                abs_path,
10239                signature,
10240            } = &symbol.path
10241            {
10242                let new_signature = this.symbol_signature(&abs_path);
10243                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10244            }
10245            Ok(())
10246        })??;
10247        let buffer = this
10248            .update(&mut cx, |this, cx| {
10249                this.open_buffer_for_symbol(
10250                    &Symbol {
10251                        language_server_name: symbol.language_server_name,
10252                        source_worktree_id: symbol.source_worktree_id,
10253                        source_language_server_id: symbol.source_language_server_id,
10254                        path: symbol.path,
10255                        name: symbol.name,
10256                        kind: symbol.kind,
10257                        range: symbol.range,
10258                        label: CodeLabel::default(),
10259                    },
10260                    cx,
10261                )
10262            })?
10263            .await?;
10264
10265        this.update(&mut cx, |this, cx| {
10266            let is_private = buffer
10267                .read(cx)
10268                .file()
10269                .map(|f| f.is_private())
10270                .unwrap_or_default();
10271            if is_private {
10272                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10273            } else {
10274                this.buffer_store
10275                    .update(cx, |buffer_store, cx| {
10276                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10277                    })
10278                    .detach_and_log_err(cx);
10279                let buffer_id = buffer.read(cx).remote_id().to_proto();
10280                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10281            }
10282        })?
10283    }
10284
10285    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10286        let mut hasher = Sha256::new();
10287        hasher.update(abs_path.to_string_lossy().as_bytes());
10288        hasher.update(self.nonce.to_be_bytes());
10289        hasher.finalize().as_slice().try_into().unwrap()
10290    }
10291
10292    pub async fn handle_get_project_symbols(
10293        this: Entity<Self>,
10294        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10295        mut cx: AsyncApp,
10296    ) -> Result<proto::GetProjectSymbolsResponse> {
10297        let symbols = this
10298            .update(&mut cx, |this, cx| {
10299                this.symbols(&envelope.payload.query, cx)
10300            })?
10301            .await?;
10302
10303        Ok(proto::GetProjectSymbolsResponse {
10304            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10305        })
10306    }
10307
10308    pub async fn handle_restart_language_servers(
10309        this: Entity<Self>,
10310        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10311        mut cx: AsyncApp,
10312    ) -> Result<proto::Ack> {
10313        this.update(&mut cx, |lsp_store, cx| {
10314            let buffers =
10315                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10316            lsp_store.restart_language_servers_for_buffers(
10317                buffers,
10318                envelope
10319                    .payload
10320                    .only_servers
10321                    .into_iter()
10322                    .filter_map(|selector| {
10323                        Some(match selector.selector? {
10324                            proto::language_server_selector::Selector::ServerId(server_id) => {
10325                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10326                            }
10327                            proto::language_server_selector::Selector::Name(name) => {
10328                                LanguageServerSelector::Name(LanguageServerName(
10329                                    SharedString::from(name),
10330                                ))
10331                            }
10332                        })
10333                    })
10334                    .collect(),
10335                cx,
10336            );
10337        })?;
10338
10339        Ok(proto::Ack {})
10340    }
10341
10342    pub async fn handle_stop_language_servers(
10343        lsp_store: Entity<Self>,
10344        envelope: TypedEnvelope<proto::StopLanguageServers>,
10345        mut cx: AsyncApp,
10346    ) -> Result<proto::Ack> {
10347        lsp_store.update(&mut cx, |lsp_store, cx| {
10348            if envelope.payload.all
10349                && envelope.payload.also_servers.is_empty()
10350                && envelope.payload.buffer_ids.is_empty()
10351            {
10352                lsp_store.stop_all_language_servers(cx);
10353            } else {
10354                let buffers =
10355                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10356                lsp_store
10357                    .stop_language_servers_for_buffers(
10358                        buffers,
10359                        envelope
10360                            .payload
10361                            .also_servers
10362                            .into_iter()
10363                            .filter_map(|selector| {
10364                                Some(match selector.selector? {
10365                                    proto::language_server_selector::Selector::ServerId(
10366                                        server_id,
10367                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10368                                        server_id,
10369                                    )),
10370                                    proto::language_server_selector::Selector::Name(name) => {
10371                                        LanguageServerSelector::Name(LanguageServerName(
10372                                            SharedString::from(name),
10373                                        ))
10374                                    }
10375                                })
10376                            })
10377                            .collect(),
10378                        cx,
10379                    )
10380                    .detach_and_log_err(cx);
10381            }
10382        })?;
10383
10384        Ok(proto::Ack {})
10385    }
10386
10387    pub async fn handle_cancel_language_server_work(
10388        lsp_store: Entity<Self>,
10389        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10390        mut cx: AsyncApp,
10391    ) -> Result<proto::Ack> {
10392        lsp_store.update(&mut cx, |lsp_store, cx| {
10393            if let Some(work) = envelope.payload.work {
10394                match work {
10395                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10396                        let buffers =
10397                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10398                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10399                    }
10400                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10401                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10402                        let token = work
10403                            .token
10404                            .map(|token| {
10405                                ProgressToken::from_proto(token)
10406                                    .context("invalid work progress token")
10407                            })
10408                            .transpose()?;
10409                        lsp_store.cancel_language_server_work(server_id, token, cx);
10410                    }
10411                }
10412            }
10413            anyhow::Ok(())
10414        })??;
10415
10416        Ok(proto::Ack {})
10417    }
10418
10419    fn buffer_ids_to_buffers(
10420        &mut self,
10421        buffer_ids: impl Iterator<Item = u64>,
10422        cx: &mut Context<Self>,
10423    ) -> Vec<Entity<Buffer>> {
10424        buffer_ids
10425            .into_iter()
10426            .flat_map(|buffer_id| {
10427                self.buffer_store
10428                    .read(cx)
10429                    .get(BufferId::new(buffer_id).log_err()?)
10430            })
10431            .collect::<Vec<_>>()
10432    }
10433
10434    async fn handle_apply_additional_edits_for_completion(
10435        this: Entity<Self>,
10436        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10437        mut cx: AsyncApp,
10438    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10439        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10440            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10441            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10442            let completion = Self::deserialize_completion(
10443                envelope.payload.completion.context("invalid completion")?,
10444            )?;
10445            anyhow::Ok((buffer, completion))
10446        })??;
10447
10448        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10449            this.apply_additional_edits_for_completion(
10450                buffer,
10451                Rc::new(RefCell::new(Box::new([Completion {
10452                    replace_range: completion.replace_range,
10453                    new_text: completion.new_text,
10454                    source: completion.source,
10455                    documentation: None,
10456                    label: CodeLabel::default(),
10457                    match_start: None,
10458                    snippet_deduplication_key: None,
10459                    insert_text_mode: None,
10460                    icon_path: None,
10461                    confirm: None,
10462                }]))),
10463                0,
10464                false,
10465                cx,
10466            )
10467        })?;
10468
10469        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10470            transaction: apply_additional_edits
10471                .await?
10472                .as_ref()
10473                .map(language::proto::serialize_transaction),
10474        })
10475    }
10476
10477    pub fn last_formatting_failure(&self) -> Option<&str> {
10478        self.last_formatting_failure.as_deref()
10479    }
10480
10481    pub fn reset_last_formatting_failure(&mut self) {
10482        self.last_formatting_failure = None;
10483    }
10484
10485    pub fn environment_for_buffer(
10486        &self,
10487        buffer: &Entity<Buffer>,
10488        cx: &mut Context<Self>,
10489    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10490        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10491            environment.update(cx, |env, cx| {
10492                env.buffer_environment(buffer, &self.worktree_store, cx)
10493            })
10494        } else {
10495            Task::ready(None).shared()
10496        }
10497    }
10498
10499    pub fn format(
10500        &mut self,
10501        buffers: HashSet<Entity<Buffer>>,
10502        target: LspFormatTarget,
10503        push_to_history: bool,
10504        trigger: FormatTrigger,
10505        cx: &mut Context<Self>,
10506    ) -> Task<anyhow::Result<ProjectTransaction>> {
10507        let logger = zlog::scoped!("format");
10508        if self.as_local().is_some() {
10509            zlog::trace!(logger => "Formatting locally");
10510            let logger = zlog::scoped!(logger => "local");
10511            let buffers = buffers
10512                .into_iter()
10513                .map(|buffer_handle| {
10514                    let buffer = buffer_handle.read(cx);
10515                    let buffer_abs_path = File::from_dyn(buffer.file())
10516                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10517
10518                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10519                })
10520                .collect::<Vec<_>>();
10521
10522            cx.spawn(async move |lsp_store, cx| {
10523                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10524
10525                for (handle, abs_path, id) in buffers {
10526                    let env = lsp_store
10527                        .update(cx, |lsp_store, cx| {
10528                            lsp_store.environment_for_buffer(&handle, cx)
10529                        })?
10530                        .await;
10531
10532                    let ranges = match &target {
10533                        LspFormatTarget::Buffers => None,
10534                        LspFormatTarget::Ranges(ranges) => {
10535                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10536                        }
10537                    };
10538
10539                    formattable_buffers.push(FormattableBuffer {
10540                        handle,
10541                        abs_path,
10542                        env,
10543                        ranges,
10544                    });
10545                }
10546                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10547
10548                let format_timer = zlog::time!(logger => "Formatting buffers");
10549                let result = LocalLspStore::format_locally(
10550                    lsp_store.clone(),
10551                    formattable_buffers,
10552                    push_to_history,
10553                    trigger,
10554                    logger,
10555                    cx,
10556                )
10557                .await;
10558                format_timer.end();
10559
10560                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10561
10562                lsp_store.update(cx, |lsp_store, _| {
10563                    lsp_store.update_last_formatting_failure(&result);
10564                })?;
10565
10566                result
10567            })
10568        } else if let Some((client, project_id)) = self.upstream_client() {
10569            zlog::trace!(logger => "Formatting remotely");
10570            let logger = zlog::scoped!(logger => "remote");
10571            // Don't support formatting ranges via remote
10572            match target {
10573                LspFormatTarget::Buffers => {}
10574                LspFormatTarget::Ranges(_) => {
10575                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10576                    return Task::ready(Ok(ProjectTransaction::default()));
10577                }
10578            }
10579
10580            let buffer_store = self.buffer_store();
10581            cx.spawn(async move |lsp_store, cx| {
10582                zlog::trace!(logger => "Sending remote format request");
10583                let request_timer = zlog::time!(logger => "remote format request");
10584                let result = client
10585                    .request(proto::FormatBuffers {
10586                        project_id,
10587                        trigger: trigger as i32,
10588                        buffer_ids: buffers
10589                            .iter()
10590                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10591                            .collect::<Result<_>>()?,
10592                    })
10593                    .await
10594                    .and_then(|result| result.transaction.context("missing transaction"));
10595                request_timer.end();
10596
10597                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10598
10599                lsp_store.update(cx, |lsp_store, _| {
10600                    lsp_store.update_last_formatting_failure(&result);
10601                })?;
10602
10603                let transaction_response = result?;
10604                let _timer = zlog::time!(logger => "deserializing project transaction");
10605                buffer_store
10606                    .update(cx, |buffer_store, cx| {
10607                        buffer_store.deserialize_project_transaction(
10608                            transaction_response,
10609                            push_to_history,
10610                            cx,
10611                        )
10612                    })?
10613                    .await
10614            })
10615        } else {
10616            zlog::trace!(logger => "Not formatting");
10617            Task::ready(Ok(ProjectTransaction::default()))
10618        }
10619    }
10620
10621    async fn handle_format_buffers(
10622        this: Entity<Self>,
10623        envelope: TypedEnvelope<proto::FormatBuffers>,
10624        mut cx: AsyncApp,
10625    ) -> Result<proto::FormatBuffersResponse> {
10626        let sender_id = envelope.original_sender_id().unwrap_or_default();
10627        let format = this.update(&mut cx, |this, cx| {
10628            let mut buffers = HashSet::default();
10629            for buffer_id in &envelope.payload.buffer_ids {
10630                let buffer_id = BufferId::new(*buffer_id)?;
10631                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10632            }
10633            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10634            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10635        })??;
10636
10637        let project_transaction = format.await?;
10638        let project_transaction = this.update(&mut cx, |this, cx| {
10639            this.buffer_store.update(cx, |buffer_store, cx| {
10640                buffer_store.serialize_project_transaction_for_peer(
10641                    project_transaction,
10642                    sender_id,
10643                    cx,
10644                )
10645            })
10646        })?;
10647        Ok(proto::FormatBuffersResponse {
10648            transaction: Some(project_transaction),
10649        })
10650    }
10651
10652    async fn handle_apply_code_action_kind(
10653        this: Entity<Self>,
10654        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10655        mut cx: AsyncApp,
10656    ) -> Result<proto::ApplyCodeActionKindResponse> {
10657        let sender_id = envelope.original_sender_id().unwrap_or_default();
10658        let format = this.update(&mut cx, |this, cx| {
10659            let mut buffers = HashSet::default();
10660            for buffer_id in &envelope.payload.buffer_ids {
10661                let buffer_id = BufferId::new(*buffer_id)?;
10662                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10663            }
10664            let kind = match envelope.payload.kind.as_str() {
10665                "" => CodeActionKind::EMPTY,
10666                "quickfix" => CodeActionKind::QUICKFIX,
10667                "refactor" => CodeActionKind::REFACTOR,
10668                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10669                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10670                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10671                "source" => CodeActionKind::SOURCE,
10672                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10673                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10674                _ => anyhow::bail!(
10675                    "Invalid code action kind {}",
10676                    envelope.payload.kind.as_str()
10677                ),
10678            };
10679            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10680        })??;
10681
10682        let project_transaction = format.await?;
10683        let project_transaction = this.update(&mut cx, |this, cx| {
10684            this.buffer_store.update(cx, |buffer_store, cx| {
10685                buffer_store.serialize_project_transaction_for_peer(
10686                    project_transaction,
10687                    sender_id,
10688                    cx,
10689                )
10690            })
10691        })?;
10692        Ok(proto::ApplyCodeActionKindResponse {
10693            transaction: Some(project_transaction),
10694        })
10695    }
10696
10697    async fn shutdown_language_server(
10698        server_state: Option<LanguageServerState>,
10699        name: LanguageServerName,
10700        cx: &mut AsyncApp,
10701    ) {
10702        let server = match server_state {
10703            Some(LanguageServerState::Starting { startup, .. }) => {
10704                let mut timer = cx
10705                    .background_executor()
10706                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10707                    .fuse();
10708
10709                select! {
10710                    server = startup.fuse() => server,
10711                    () = timer => {
10712                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10713                        None
10714                    },
10715                }
10716            }
10717
10718            Some(LanguageServerState::Running { server, .. }) => Some(server),
10719
10720            None => None,
10721        };
10722
10723        if let Some(server) = server
10724            && let Some(shutdown) = server.shutdown()
10725        {
10726            shutdown.await;
10727        }
10728    }
10729
10730    // Returns a list of all of the worktrees which no longer have a language server and the root path
10731    // for the stopped server
10732    fn stop_local_language_server(
10733        &mut self,
10734        server_id: LanguageServerId,
10735        cx: &mut Context<Self>,
10736    ) -> Task<()> {
10737        let local = match &mut self.mode {
10738            LspStoreMode::Local(local) => local,
10739            _ => {
10740                return Task::ready(());
10741            }
10742        };
10743
10744        // Remove this server ID from all entries in the given worktree.
10745        local
10746            .language_server_ids
10747            .retain(|_, state| state.id != server_id);
10748        self.buffer_store.update(cx, |buffer_store, cx| {
10749            for buffer in buffer_store.buffers() {
10750                buffer.update(cx, |buffer, cx| {
10751                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10752                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10753                });
10754            }
10755        });
10756
10757        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10758            summaries.retain(|path, summaries_by_server_id| {
10759                if summaries_by_server_id.remove(&server_id).is_some() {
10760                    if let Some((client, project_id)) = self.downstream_client.clone() {
10761                        client
10762                            .send(proto::UpdateDiagnosticSummary {
10763                                project_id,
10764                                worktree_id: worktree_id.to_proto(),
10765                                summary: Some(proto::DiagnosticSummary {
10766                                    path: path.as_ref().to_proto(),
10767                                    language_server_id: server_id.0 as u64,
10768                                    error_count: 0,
10769                                    warning_count: 0,
10770                                }),
10771                                more_summaries: Vec::new(),
10772                            })
10773                            .log_err();
10774                    }
10775                    !summaries_by_server_id.is_empty()
10776                } else {
10777                    true
10778                }
10779            });
10780        }
10781
10782        let local = self.as_local_mut().unwrap();
10783        for diagnostics in local.diagnostics.values_mut() {
10784            diagnostics.retain(|_, diagnostics_by_server_id| {
10785                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10786                    diagnostics_by_server_id.remove(ix);
10787                    !diagnostics_by_server_id.is_empty()
10788                } else {
10789                    true
10790                }
10791            });
10792        }
10793        local.language_server_watched_paths.remove(&server_id);
10794
10795        let server_state = local.language_servers.remove(&server_id);
10796        self.cleanup_lsp_data(server_id);
10797        let name = self
10798            .language_server_statuses
10799            .remove(&server_id)
10800            .map(|status| status.name)
10801            .or_else(|| {
10802                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10803                    Some(adapter.name())
10804                } else {
10805                    None
10806                }
10807            });
10808
10809        if let Some(name) = name {
10810            log::info!("stopping language server {name}");
10811            self.languages
10812                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10813            cx.notify();
10814
10815            return cx.spawn(async move |lsp_store, cx| {
10816                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10817                lsp_store
10818                    .update(cx, |lsp_store, cx| {
10819                        lsp_store
10820                            .languages
10821                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10822                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10823                        cx.notify();
10824                    })
10825                    .ok();
10826            });
10827        }
10828
10829        if server_state.is_some() {
10830            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10831        }
10832        Task::ready(())
10833    }
10834
10835    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10836        if let Some((client, project_id)) = self.upstream_client() {
10837            let request = client.request(proto::StopLanguageServers {
10838                project_id,
10839                buffer_ids: Vec::new(),
10840                also_servers: Vec::new(),
10841                all: true,
10842            });
10843            cx.background_spawn(request).detach_and_log_err(cx);
10844        } else {
10845            let Some(local) = self.as_local_mut() else {
10846                return;
10847            };
10848            let language_servers_to_stop = local
10849                .language_server_ids
10850                .values()
10851                .map(|state| state.id)
10852                .collect();
10853            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10854            let tasks = language_servers_to_stop
10855                .into_iter()
10856                .map(|server| self.stop_local_language_server(server, cx))
10857                .collect::<Vec<_>>();
10858            cx.background_spawn(async move {
10859                futures::future::join_all(tasks).await;
10860            })
10861            .detach();
10862        }
10863    }
10864
10865    pub fn restart_language_servers_for_buffers(
10866        &mut self,
10867        buffers: Vec<Entity<Buffer>>,
10868        only_restart_servers: HashSet<LanguageServerSelector>,
10869        cx: &mut Context<Self>,
10870    ) {
10871        if let Some((client, project_id)) = self.upstream_client() {
10872            let request = client.request(proto::RestartLanguageServers {
10873                project_id,
10874                buffer_ids: buffers
10875                    .into_iter()
10876                    .map(|b| b.read(cx).remote_id().to_proto())
10877                    .collect(),
10878                only_servers: only_restart_servers
10879                    .into_iter()
10880                    .map(|selector| {
10881                        let selector = match selector {
10882                            LanguageServerSelector::Id(language_server_id) => {
10883                                proto::language_server_selector::Selector::ServerId(
10884                                    language_server_id.to_proto(),
10885                                )
10886                            }
10887                            LanguageServerSelector::Name(language_server_name) => {
10888                                proto::language_server_selector::Selector::Name(
10889                                    language_server_name.to_string(),
10890                                )
10891                            }
10892                        };
10893                        proto::LanguageServerSelector {
10894                            selector: Some(selector),
10895                        }
10896                    })
10897                    .collect(),
10898                all: false,
10899            });
10900            cx.background_spawn(request).detach_and_log_err(cx);
10901        } else {
10902            let stop_task = if only_restart_servers.is_empty() {
10903                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10904            } else {
10905                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10906            };
10907            cx.spawn(async move |lsp_store, cx| {
10908                stop_task.await;
10909                lsp_store
10910                    .update(cx, |lsp_store, cx| {
10911                        for buffer in buffers {
10912                            lsp_store.register_buffer_with_language_servers(
10913                                &buffer,
10914                                only_restart_servers.clone(),
10915                                true,
10916                                cx,
10917                            );
10918                        }
10919                    })
10920                    .ok()
10921            })
10922            .detach();
10923        }
10924    }
10925
10926    pub fn stop_language_servers_for_buffers(
10927        &mut self,
10928        buffers: Vec<Entity<Buffer>>,
10929        also_stop_servers: HashSet<LanguageServerSelector>,
10930        cx: &mut Context<Self>,
10931    ) -> Task<Result<()>> {
10932        if let Some((client, project_id)) = self.upstream_client() {
10933            let request = client.request(proto::StopLanguageServers {
10934                project_id,
10935                buffer_ids: buffers
10936                    .into_iter()
10937                    .map(|b| b.read(cx).remote_id().to_proto())
10938                    .collect(),
10939                also_servers: also_stop_servers
10940                    .into_iter()
10941                    .map(|selector| {
10942                        let selector = match selector {
10943                            LanguageServerSelector::Id(language_server_id) => {
10944                                proto::language_server_selector::Selector::ServerId(
10945                                    language_server_id.to_proto(),
10946                                )
10947                            }
10948                            LanguageServerSelector::Name(language_server_name) => {
10949                                proto::language_server_selector::Selector::Name(
10950                                    language_server_name.to_string(),
10951                                )
10952                            }
10953                        };
10954                        proto::LanguageServerSelector {
10955                            selector: Some(selector),
10956                        }
10957                    })
10958                    .collect(),
10959                all: false,
10960            });
10961            cx.background_spawn(async move {
10962                let _ = request.await?;
10963                Ok(())
10964            })
10965        } else {
10966            let task =
10967                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10968            cx.background_spawn(async move {
10969                task.await;
10970                Ok(())
10971            })
10972        }
10973    }
10974
10975    fn stop_local_language_servers_for_buffers(
10976        &mut self,
10977        buffers: &[Entity<Buffer>],
10978        also_stop_servers: HashSet<LanguageServerSelector>,
10979        cx: &mut Context<Self>,
10980    ) -> Task<()> {
10981        let Some(local) = self.as_local_mut() else {
10982            return Task::ready(());
10983        };
10984        let mut language_server_names_to_stop = BTreeSet::default();
10985        let mut language_servers_to_stop = also_stop_servers
10986            .into_iter()
10987            .flat_map(|selector| match selector {
10988                LanguageServerSelector::Id(id) => Some(id),
10989                LanguageServerSelector::Name(name) => {
10990                    language_server_names_to_stop.insert(name);
10991                    None
10992                }
10993            })
10994            .collect::<BTreeSet<_>>();
10995
10996        let mut covered_worktrees = HashSet::default();
10997        for buffer in buffers {
10998            buffer.update(cx, |buffer, cx| {
10999                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11000                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11001                    && covered_worktrees.insert(worktree_id)
11002                {
11003                    language_server_names_to_stop.retain(|name| {
11004                        let old_ids_count = language_servers_to_stop.len();
11005                        let all_language_servers_with_this_name = local
11006                            .language_server_ids
11007                            .iter()
11008                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11009                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11010                        old_ids_count == language_servers_to_stop.len()
11011                    });
11012                }
11013            });
11014        }
11015        for name in language_server_names_to_stop {
11016            language_servers_to_stop.extend(
11017                local
11018                    .language_server_ids
11019                    .iter()
11020                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11021            );
11022        }
11023
11024        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11025        let tasks = language_servers_to_stop
11026            .into_iter()
11027            .map(|server| self.stop_local_language_server(server, cx))
11028            .collect::<Vec<_>>();
11029
11030        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11031    }
11032
11033    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11034        let (worktree, relative_path) =
11035            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11036
11037        let project_path = ProjectPath {
11038            worktree_id: worktree.read(cx).id(),
11039            path: relative_path,
11040        };
11041
11042        Some(
11043            self.buffer_store()
11044                .read(cx)
11045                .get_by_path(&project_path)?
11046                .read(cx),
11047        )
11048    }
11049
11050    #[cfg(any(test, feature = "test-support"))]
11051    pub fn update_diagnostics(
11052        &mut self,
11053        server_id: LanguageServerId,
11054        diagnostics: lsp::PublishDiagnosticsParams,
11055        result_id: Option<SharedString>,
11056        source_kind: DiagnosticSourceKind,
11057        disk_based_sources: &[String],
11058        cx: &mut Context<Self>,
11059    ) -> Result<()> {
11060        self.merge_lsp_diagnostics(
11061            source_kind,
11062            vec![DocumentDiagnosticsUpdate {
11063                diagnostics,
11064                result_id,
11065                server_id,
11066                disk_based_sources: Cow::Borrowed(disk_based_sources),
11067                registration_id: None,
11068            }],
11069            |_, _, _| false,
11070            cx,
11071        )
11072    }
11073
11074    pub fn merge_lsp_diagnostics(
11075        &mut self,
11076        source_kind: DiagnosticSourceKind,
11077        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11078        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11079        cx: &mut Context<Self>,
11080    ) -> Result<()> {
11081        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11082        let updates = lsp_diagnostics
11083            .into_iter()
11084            .filter_map(|update| {
11085                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11086                Some(DocumentDiagnosticsUpdate {
11087                    diagnostics: self.lsp_to_document_diagnostics(
11088                        abs_path,
11089                        source_kind,
11090                        update.server_id,
11091                        update.diagnostics,
11092                        &update.disk_based_sources,
11093                        update.registration_id.clone(),
11094                    ),
11095                    result_id: update.result_id,
11096                    server_id: update.server_id,
11097                    disk_based_sources: update.disk_based_sources,
11098                    registration_id: update.registration_id,
11099                })
11100            })
11101            .collect();
11102        self.merge_diagnostic_entries(updates, merge, cx)?;
11103        Ok(())
11104    }
11105
11106    fn lsp_to_document_diagnostics(
11107        &mut self,
11108        document_abs_path: PathBuf,
11109        source_kind: DiagnosticSourceKind,
11110        server_id: LanguageServerId,
11111        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11112        disk_based_sources: &[String],
11113        registration_id: Option<SharedString>,
11114    ) -> DocumentDiagnostics {
11115        let mut diagnostics = Vec::default();
11116        let mut primary_diagnostic_group_ids = HashMap::default();
11117        let mut sources_by_group_id = HashMap::default();
11118        let mut supporting_diagnostics = HashMap::default();
11119
11120        let adapter = self.language_server_adapter_for_id(server_id);
11121
11122        // Ensure that primary diagnostics are always the most severe
11123        lsp_diagnostics
11124            .diagnostics
11125            .sort_by_key(|item| item.severity);
11126
11127        for diagnostic in &lsp_diagnostics.diagnostics {
11128            let source = diagnostic.source.as_ref();
11129            let range = range_from_lsp(diagnostic.range);
11130            let is_supporting = diagnostic
11131                .related_information
11132                .as_ref()
11133                .is_some_and(|infos| {
11134                    infos.iter().any(|info| {
11135                        primary_diagnostic_group_ids.contains_key(&(
11136                            source,
11137                            diagnostic.code.clone(),
11138                            range_from_lsp(info.location.range),
11139                        ))
11140                    })
11141                });
11142
11143            let is_unnecessary = diagnostic
11144                .tags
11145                .as_ref()
11146                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11147
11148            let underline = self
11149                .language_server_adapter_for_id(server_id)
11150                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11151
11152            if is_supporting {
11153                supporting_diagnostics.insert(
11154                    (source, diagnostic.code.clone(), range),
11155                    (diagnostic.severity, is_unnecessary),
11156                );
11157            } else {
11158                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11159                let is_disk_based =
11160                    source.is_some_and(|source| disk_based_sources.contains(source));
11161
11162                sources_by_group_id.insert(group_id, source);
11163                primary_diagnostic_group_ids
11164                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11165
11166                diagnostics.push(DiagnosticEntry {
11167                    range,
11168                    diagnostic: Diagnostic {
11169                        source: diagnostic.source.clone(),
11170                        source_kind,
11171                        code: diagnostic.code.clone(),
11172                        code_description: diagnostic
11173                            .code_description
11174                            .as_ref()
11175                            .and_then(|d| d.href.clone()),
11176                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11177                        markdown: adapter.as_ref().and_then(|adapter| {
11178                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11179                        }),
11180                        message: diagnostic.message.trim().to_string(),
11181                        group_id,
11182                        is_primary: true,
11183                        is_disk_based,
11184                        is_unnecessary,
11185                        underline,
11186                        data: diagnostic.data.clone(),
11187                        registration_id: registration_id.clone(),
11188                    },
11189                });
11190                if let Some(infos) = &diagnostic.related_information {
11191                    for info in infos {
11192                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11193                            let range = range_from_lsp(info.location.range);
11194                            diagnostics.push(DiagnosticEntry {
11195                                range,
11196                                diagnostic: Diagnostic {
11197                                    source: diagnostic.source.clone(),
11198                                    source_kind,
11199                                    code: diagnostic.code.clone(),
11200                                    code_description: diagnostic
11201                                        .code_description
11202                                        .as_ref()
11203                                        .and_then(|d| d.href.clone()),
11204                                    severity: DiagnosticSeverity::INFORMATION,
11205                                    markdown: adapter.as_ref().and_then(|adapter| {
11206                                        adapter.diagnostic_message_to_markdown(&info.message)
11207                                    }),
11208                                    message: info.message.trim().to_string(),
11209                                    group_id,
11210                                    is_primary: false,
11211                                    is_disk_based,
11212                                    is_unnecessary: false,
11213                                    underline,
11214                                    data: diagnostic.data.clone(),
11215                                    registration_id: registration_id.clone(),
11216                                },
11217                            });
11218                        }
11219                    }
11220                }
11221            }
11222        }
11223
11224        for entry in &mut diagnostics {
11225            let diagnostic = &mut entry.diagnostic;
11226            if !diagnostic.is_primary {
11227                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11228                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11229                    source,
11230                    diagnostic.code.clone(),
11231                    entry.range.clone(),
11232                )) {
11233                    if let Some(severity) = severity {
11234                        diagnostic.severity = severity;
11235                    }
11236                    diagnostic.is_unnecessary = is_unnecessary;
11237                }
11238            }
11239        }
11240
11241        DocumentDiagnostics {
11242            diagnostics,
11243            document_abs_path,
11244            version: lsp_diagnostics.version,
11245        }
11246    }
11247
11248    fn insert_newly_running_language_server(
11249        &mut self,
11250        adapter: Arc<CachedLspAdapter>,
11251        language_server: Arc<LanguageServer>,
11252        server_id: LanguageServerId,
11253        key: LanguageServerSeed,
11254        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11255        cx: &mut Context<Self>,
11256    ) {
11257        let Some(local) = self.as_local_mut() else {
11258            return;
11259        };
11260        // If the language server for this key doesn't match the server id, don't store the
11261        // server. Which will cause it to be dropped, killing the process
11262        if local
11263            .language_server_ids
11264            .get(&key)
11265            .map(|state| state.id != server_id)
11266            .unwrap_or(false)
11267        {
11268            return;
11269        }
11270
11271        // Update language_servers collection with Running variant of LanguageServerState
11272        // indicating that the server is up and running and ready
11273        let workspace_folders = workspace_folders.lock().clone();
11274        language_server.set_workspace_folders(workspace_folders);
11275
11276        let workspace_diagnostics_refresh_tasks = language_server
11277            .capabilities()
11278            .diagnostic_provider
11279            .and_then(|provider| {
11280                local
11281                    .language_server_dynamic_registrations
11282                    .entry(server_id)
11283                    .or_default()
11284                    .diagnostics
11285                    .entry(None)
11286                    .or_insert(provider.clone());
11287                let workspace_refresher =
11288                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11289
11290                Some((None, workspace_refresher))
11291            })
11292            .into_iter()
11293            .collect();
11294        local.language_servers.insert(
11295            server_id,
11296            LanguageServerState::Running {
11297                workspace_diagnostics_refresh_tasks,
11298                adapter: adapter.clone(),
11299                server: language_server.clone(),
11300                simulate_disk_based_diagnostics_completion: None,
11301            },
11302        );
11303        local
11304            .languages
11305            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11306        if let Some(file_ops_caps) = language_server
11307            .capabilities()
11308            .workspace
11309            .as_ref()
11310            .and_then(|ws| ws.file_operations.as_ref())
11311        {
11312            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11313            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11314            if did_rename_caps.or(will_rename_caps).is_some() {
11315                let watcher = RenamePathsWatchedForServer::default()
11316                    .with_did_rename_patterns(did_rename_caps)
11317                    .with_will_rename_patterns(will_rename_caps);
11318                local
11319                    .language_server_paths_watched_for_rename
11320                    .insert(server_id, watcher);
11321            }
11322        }
11323
11324        self.language_server_statuses.insert(
11325            server_id,
11326            LanguageServerStatus {
11327                name: language_server.name(),
11328                pending_work: Default::default(),
11329                has_pending_diagnostic_updates: false,
11330                progress_tokens: Default::default(),
11331                worktree: Some(key.worktree_id),
11332                binary: Some(language_server.binary().clone()),
11333                configuration: Some(language_server.configuration().clone()),
11334                workspace_folders: language_server.workspace_folders(),
11335            },
11336        );
11337
11338        cx.emit(LspStoreEvent::LanguageServerAdded(
11339            server_id,
11340            language_server.name(),
11341            Some(key.worktree_id),
11342        ));
11343
11344        let server_capabilities = language_server.capabilities();
11345        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11346            downstream_client
11347                .send(proto::StartLanguageServer {
11348                    project_id: *project_id,
11349                    server: Some(proto::LanguageServer {
11350                        id: server_id.to_proto(),
11351                        name: language_server.name().to_string(),
11352                        worktree_id: Some(key.worktree_id.to_proto()),
11353                    }),
11354                    capabilities: serde_json::to_string(&server_capabilities)
11355                        .expect("serializing server LSP capabilities"),
11356                })
11357                .log_err();
11358        }
11359        self.lsp_server_capabilities
11360            .insert(server_id, server_capabilities);
11361
11362        // Tell the language server about every open buffer in the worktree that matches the language.
11363        // Also check for buffers in worktrees that reused this server
11364        let mut worktrees_using_server = vec![key.worktree_id];
11365        if let Some(local) = self.as_local() {
11366            // Find all worktrees that have this server in their language server tree
11367            for (worktree_id, servers) in &local.lsp_tree.instances {
11368                if *worktree_id != key.worktree_id {
11369                    for server_map in servers.roots.values() {
11370                        if server_map
11371                            .values()
11372                            .any(|(node, _)| node.id() == Some(server_id))
11373                        {
11374                            worktrees_using_server.push(*worktree_id);
11375                        }
11376                    }
11377                }
11378            }
11379        }
11380
11381        let mut buffer_paths_registered = Vec::new();
11382        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11383            let mut lsp_adapters = HashMap::default();
11384            for buffer_handle in buffer_store.buffers() {
11385                let buffer = buffer_handle.read(cx);
11386                let file = match File::from_dyn(buffer.file()) {
11387                    Some(file) => file,
11388                    None => continue,
11389                };
11390                let language = match buffer.language() {
11391                    Some(language) => language,
11392                    None => continue,
11393                };
11394
11395                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11396                    || !lsp_adapters
11397                        .entry(language.name())
11398                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11399                        .iter()
11400                        .any(|a| a.name == key.name)
11401                {
11402                    continue;
11403                }
11404                // didOpen
11405                let file = match file.as_local() {
11406                    Some(file) => file,
11407                    None => continue,
11408                };
11409
11410                let local = self.as_local_mut().unwrap();
11411
11412                let buffer_id = buffer.remote_id();
11413                if local.registered_buffers.contains_key(&buffer_id) {
11414                    let versions = local
11415                        .buffer_snapshots
11416                        .entry(buffer_id)
11417                        .or_default()
11418                        .entry(server_id)
11419                        .and_modify(|_| {
11420                            assert!(
11421                            false,
11422                            "There should not be an existing snapshot for a newly inserted buffer"
11423                        )
11424                        })
11425                        .or_insert_with(|| {
11426                            vec![LspBufferSnapshot {
11427                                version: 0,
11428                                snapshot: buffer.text_snapshot(),
11429                            }]
11430                        });
11431
11432                    let snapshot = versions.last().unwrap();
11433                    let version = snapshot.version;
11434                    let initial_snapshot = &snapshot.snapshot;
11435                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11436                    language_server.register_buffer(
11437                        uri,
11438                        adapter.language_id(&language.name()),
11439                        version,
11440                        initial_snapshot.text(),
11441                    );
11442                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11443                    local
11444                        .buffers_opened_in_servers
11445                        .entry(buffer_id)
11446                        .or_default()
11447                        .insert(server_id);
11448                }
11449                buffer_handle.update(cx, |buffer, cx| {
11450                    buffer.set_completion_triggers(
11451                        server_id,
11452                        language_server
11453                            .capabilities()
11454                            .completion_provider
11455                            .as_ref()
11456                            .and_then(|provider| {
11457                                provider
11458                                    .trigger_characters
11459                                    .as_ref()
11460                                    .map(|characters| characters.iter().cloned().collect())
11461                            })
11462                            .unwrap_or_default(),
11463                        cx,
11464                    )
11465                });
11466            }
11467        });
11468
11469        for (buffer_id, abs_path) in buffer_paths_registered {
11470            cx.emit(LspStoreEvent::LanguageServerUpdate {
11471                language_server_id: server_id,
11472                name: Some(adapter.name()),
11473                message: proto::update_language_server::Variant::RegisteredForBuffer(
11474                    proto::RegisteredForBuffer {
11475                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11476                        buffer_id: buffer_id.to_proto(),
11477                    },
11478                ),
11479            });
11480        }
11481
11482        cx.notify();
11483    }
11484
11485    pub fn language_servers_running_disk_based_diagnostics(
11486        &self,
11487    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11488        self.language_server_statuses
11489            .iter()
11490            .filter_map(|(id, status)| {
11491                if status.has_pending_diagnostic_updates {
11492                    Some(*id)
11493                } else {
11494                    None
11495                }
11496            })
11497    }
11498
11499    pub(crate) fn cancel_language_server_work_for_buffers(
11500        &mut self,
11501        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11502        cx: &mut Context<Self>,
11503    ) {
11504        if let Some((client, project_id)) = self.upstream_client() {
11505            let request = client.request(proto::CancelLanguageServerWork {
11506                project_id,
11507                work: Some(proto::cancel_language_server_work::Work::Buffers(
11508                    proto::cancel_language_server_work::Buffers {
11509                        buffer_ids: buffers
11510                            .into_iter()
11511                            .map(|b| b.read(cx).remote_id().to_proto())
11512                            .collect(),
11513                    },
11514                )),
11515            });
11516            cx.background_spawn(request).detach_and_log_err(cx);
11517        } else if let Some(local) = self.as_local() {
11518            let servers = buffers
11519                .into_iter()
11520                .flat_map(|buffer| {
11521                    buffer.update(cx, |buffer, cx| {
11522                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11523                    })
11524                })
11525                .collect::<HashSet<_>>();
11526            for server_id in servers {
11527                self.cancel_language_server_work(server_id, None, cx);
11528            }
11529        }
11530    }
11531
11532    pub(crate) fn cancel_language_server_work(
11533        &mut self,
11534        server_id: LanguageServerId,
11535        token_to_cancel: Option<ProgressToken>,
11536        cx: &mut Context<Self>,
11537    ) {
11538        if let Some(local) = self.as_local() {
11539            let status = self.language_server_statuses.get(&server_id);
11540            let server = local.language_servers.get(&server_id);
11541            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11542            {
11543                for (token, progress) in &status.pending_work {
11544                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11545                        && token != token_to_cancel
11546                    {
11547                        continue;
11548                    }
11549                    if progress.is_cancellable {
11550                        server
11551                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11552                                WorkDoneProgressCancelParams {
11553                                    token: token.to_lsp(),
11554                                },
11555                            )
11556                            .ok();
11557                    }
11558                }
11559            }
11560        } else if let Some((client, project_id)) = self.upstream_client() {
11561            let request = client.request(proto::CancelLanguageServerWork {
11562                project_id,
11563                work: Some(
11564                    proto::cancel_language_server_work::Work::LanguageServerWork(
11565                        proto::cancel_language_server_work::LanguageServerWork {
11566                            language_server_id: server_id.to_proto(),
11567                            token: token_to_cancel.map(|token| token.to_proto()),
11568                        },
11569                    ),
11570                ),
11571            });
11572            cx.background_spawn(request).detach_and_log_err(cx);
11573        }
11574    }
11575
11576    fn register_supplementary_language_server(
11577        &mut self,
11578        id: LanguageServerId,
11579        name: LanguageServerName,
11580        server: Arc<LanguageServer>,
11581        cx: &mut Context<Self>,
11582    ) {
11583        if let Some(local) = self.as_local_mut() {
11584            local
11585                .supplementary_language_servers
11586                .insert(id, (name.clone(), server));
11587            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11588        }
11589    }
11590
11591    fn unregister_supplementary_language_server(
11592        &mut self,
11593        id: LanguageServerId,
11594        cx: &mut Context<Self>,
11595    ) {
11596        if let Some(local) = self.as_local_mut() {
11597            local.supplementary_language_servers.remove(&id);
11598            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11599        }
11600    }
11601
11602    pub(crate) fn supplementary_language_servers(
11603        &self,
11604    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11605        self.as_local().into_iter().flat_map(|local| {
11606            local
11607                .supplementary_language_servers
11608                .iter()
11609                .map(|(id, (name, _))| (*id, name.clone()))
11610        })
11611    }
11612
11613    pub fn language_server_adapter_for_id(
11614        &self,
11615        id: LanguageServerId,
11616    ) -> Option<Arc<CachedLspAdapter>> {
11617        self.as_local()
11618            .and_then(|local| local.language_servers.get(&id))
11619            .and_then(|language_server_state| match language_server_state {
11620                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11621                _ => None,
11622            })
11623    }
11624
11625    pub(super) fn update_local_worktree_language_servers(
11626        &mut self,
11627        worktree_handle: &Entity<Worktree>,
11628        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11629        cx: &mut Context<Self>,
11630    ) {
11631        if changes.is_empty() {
11632            return;
11633        }
11634
11635        let Some(local) = self.as_local() else { return };
11636
11637        local.prettier_store.update(cx, |prettier_store, cx| {
11638            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11639        });
11640
11641        let worktree_id = worktree_handle.read(cx).id();
11642        let mut language_server_ids = local
11643            .language_server_ids
11644            .iter()
11645            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11646            .collect::<Vec<_>>();
11647        language_server_ids.sort();
11648        language_server_ids.dedup();
11649
11650        // let abs_path = worktree_handle.read(cx).abs_path();
11651        for server_id in &language_server_ids {
11652            if let Some(LanguageServerState::Running { server, .. }) =
11653                local.language_servers.get(server_id)
11654                && let Some(watched_paths) = local
11655                    .language_server_watched_paths
11656                    .get(server_id)
11657                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11658            {
11659                let params = lsp::DidChangeWatchedFilesParams {
11660                    changes: changes
11661                        .iter()
11662                        .filter_map(|(path, _, change)| {
11663                            if !watched_paths.is_match(path.as_std_path()) {
11664                                return None;
11665                            }
11666                            let typ = match change {
11667                                PathChange::Loaded => return None,
11668                                PathChange::Added => lsp::FileChangeType::CREATED,
11669                                PathChange::Removed => lsp::FileChangeType::DELETED,
11670                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11671                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11672                            };
11673                            let uri = lsp::Uri::from_file_path(
11674                                worktree_handle.read(cx).absolutize(&path),
11675                            )
11676                            .ok()?;
11677                            Some(lsp::FileEvent { uri, typ })
11678                        })
11679                        .collect(),
11680                };
11681                if !params.changes.is_empty() {
11682                    server
11683                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11684                        .ok();
11685                }
11686            }
11687        }
11688        for (path, _, _) in changes {
11689            if let Some(file_name) = path.file_name()
11690                && local.watched_manifest_filenames.contains(file_name)
11691            {
11692                self.request_workspace_config_refresh();
11693                break;
11694            }
11695        }
11696    }
11697
11698    pub fn wait_for_remote_buffer(
11699        &mut self,
11700        id: BufferId,
11701        cx: &mut Context<Self>,
11702    ) -> Task<Result<Entity<Buffer>>> {
11703        self.buffer_store.update(cx, |buffer_store, cx| {
11704            buffer_store.wait_for_remote_buffer(id, cx)
11705        })
11706    }
11707
11708    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11709        let mut result = proto::Symbol {
11710            language_server_name: symbol.language_server_name.0.to_string(),
11711            source_worktree_id: symbol.source_worktree_id.to_proto(),
11712            language_server_id: symbol.source_language_server_id.to_proto(),
11713            name: symbol.name.clone(),
11714            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11715            start: Some(proto::PointUtf16 {
11716                row: symbol.range.start.0.row,
11717                column: symbol.range.start.0.column,
11718            }),
11719            end: Some(proto::PointUtf16 {
11720                row: symbol.range.end.0.row,
11721                column: symbol.range.end.0.column,
11722            }),
11723            worktree_id: Default::default(),
11724            path: Default::default(),
11725            signature: Default::default(),
11726        };
11727        match &symbol.path {
11728            SymbolLocation::InProject(path) => {
11729                result.worktree_id = path.worktree_id.to_proto();
11730                result.path = path.path.to_proto();
11731            }
11732            SymbolLocation::OutsideProject {
11733                abs_path,
11734                signature,
11735            } => {
11736                result.path = abs_path.to_string_lossy().into_owned();
11737                result.signature = signature.to_vec();
11738            }
11739        }
11740        result
11741    }
11742
11743    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11744        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11745        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11746        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11747
11748        let path = if serialized_symbol.signature.is_empty() {
11749            SymbolLocation::InProject(ProjectPath {
11750                worktree_id,
11751                path: RelPath::from_proto(&serialized_symbol.path)
11752                    .context("invalid symbol path")?,
11753            })
11754        } else {
11755            SymbolLocation::OutsideProject {
11756                abs_path: Path::new(&serialized_symbol.path).into(),
11757                signature: serialized_symbol
11758                    .signature
11759                    .try_into()
11760                    .map_err(|_| anyhow!("invalid signature"))?,
11761            }
11762        };
11763
11764        let start = serialized_symbol.start.context("invalid start")?;
11765        let end = serialized_symbol.end.context("invalid end")?;
11766        Ok(CoreSymbol {
11767            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11768            source_worktree_id,
11769            source_language_server_id: LanguageServerId::from_proto(
11770                serialized_symbol.language_server_id,
11771            ),
11772            path,
11773            name: serialized_symbol.name,
11774            range: Unclipped(PointUtf16::new(start.row, start.column))
11775                ..Unclipped(PointUtf16::new(end.row, end.column)),
11776            kind,
11777        })
11778    }
11779
11780    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11781        let mut serialized_completion = proto::Completion {
11782            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11783            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11784            new_text: completion.new_text.clone(),
11785            ..proto::Completion::default()
11786        };
11787        match &completion.source {
11788            CompletionSource::Lsp {
11789                insert_range,
11790                server_id,
11791                lsp_completion,
11792                lsp_defaults,
11793                resolved,
11794            } => {
11795                let (old_insert_start, old_insert_end) = insert_range
11796                    .as_ref()
11797                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11798                    .unzip();
11799
11800                serialized_completion.old_insert_start = old_insert_start;
11801                serialized_completion.old_insert_end = old_insert_end;
11802                serialized_completion.source = proto::completion::Source::Lsp as i32;
11803                serialized_completion.server_id = server_id.0 as u64;
11804                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11805                serialized_completion.lsp_defaults = lsp_defaults
11806                    .as_deref()
11807                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11808                serialized_completion.resolved = *resolved;
11809            }
11810            CompletionSource::BufferWord {
11811                word_range,
11812                resolved,
11813            } => {
11814                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11815                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11816                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11817                serialized_completion.resolved = *resolved;
11818            }
11819            CompletionSource::Custom => {
11820                serialized_completion.source = proto::completion::Source::Custom as i32;
11821                serialized_completion.resolved = true;
11822            }
11823            CompletionSource::Dap { sort_text } => {
11824                serialized_completion.source = proto::completion::Source::Dap as i32;
11825                serialized_completion.sort_text = Some(sort_text.clone());
11826            }
11827        }
11828
11829        serialized_completion
11830    }
11831
11832    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11833        let old_replace_start = completion
11834            .old_replace_start
11835            .and_then(deserialize_anchor)
11836            .context("invalid old start")?;
11837        let old_replace_end = completion
11838            .old_replace_end
11839            .and_then(deserialize_anchor)
11840            .context("invalid old end")?;
11841        let insert_range = {
11842            match completion.old_insert_start.zip(completion.old_insert_end) {
11843                Some((start, end)) => {
11844                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11845                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11846                    Some(start..end)
11847                }
11848                None => None,
11849            }
11850        };
11851        Ok(CoreCompletion {
11852            replace_range: old_replace_start..old_replace_end,
11853            new_text: completion.new_text,
11854            source: match proto::completion::Source::from_i32(completion.source) {
11855                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11856                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11857                    insert_range,
11858                    server_id: LanguageServerId::from_proto(completion.server_id),
11859                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11860                    lsp_defaults: completion
11861                        .lsp_defaults
11862                        .as_deref()
11863                        .map(serde_json::from_slice)
11864                        .transpose()?,
11865                    resolved: completion.resolved,
11866                },
11867                Some(proto::completion::Source::BufferWord) => {
11868                    let word_range = completion
11869                        .buffer_word_start
11870                        .and_then(deserialize_anchor)
11871                        .context("invalid buffer word start")?
11872                        ..completion
11873                            .buffer_word_end
11874                            .and_then(deserialize_anchor)
11875                            .context("invalid buffer word end")?;
11876                    CompletionSource::BufferWord {
11877                        word_range,
11878                        resolved: completion.resolved,
11879                    }
11880                }
11881                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11882                    sort_text: completion
11883                        .sort_text
11884                        .context("expected sort text to exist")?,
11885                },
11886                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11887            },
11888        })
11889    }
11890
11891    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11892        let (kind, lsp_action) = match &action.lsp_action {
11893            LspAction::Action(code_action) => (
11894                proto::code_action::Kind::Action as i32,
11895                serde_json::to_vec(code_action).unwrap(),
11896            ),
11897            LspAction::Command(command) => (
11898                proto::code_action::Kind::Command as i32,
11899                serde_json::to_vec(command).unwrap(),
11900            ),
11901            LspAction::CodeLens(code_lens) => (
11902                proto::code_action::Kind::CodeLens as i32,
11903                serde_json::to_vec(code_lens).unwrap(),
11904            ),
11905        };
11906
11907        proto::CodeAction {
11908            server_id: action.server_id.0 as u64,
11909            start: Some(serialize_anchor(&action.range.start)),
11910            end: Some(serialize_anchor(&action.range.end)),
11911            lsp_action,
11912            kind,
11913            resolved: action.resolved,
11914        }
11915    }
11916
11917    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11918        let start = action
11919            .start
11920            .and_then(deserialize_anchor)
11921            .context("invalid start")?;
11922        let end = action
11923            .end
11924            .and_then(deserialize_anchor)
11925            .context("invalid end")?;
11926        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11927            Some(proto::code_action::Kind::Action) => {
11928                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11929            }
11930            Some(proto::code_action::Kind::Command) => {
11931                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11932            }
11933            Some(proto::code_action::Kind::CodeLens) => {
11934                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11935            }
11936            None => anyhow::bail!("Unknown action kind {}", action.kind),
11937        };
11938        Ok(CodeAction {
11939            server_id: LanguageServerId(action.server_id as usize),
11940            range: start..end,
11941            resolved: action.resolved,
11942            lsp_action,
11943        })
11944    }
11945
11946    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11947        match &formatting_result {
11948            Ok(_) => self.last_formatting_failure = None,
11949            Err(error) => {
11950                let error_string = format!("{error:#}");
11951                log::error!("Formatting failed: {error_string}");
11952                self.last_formatting_failure
11953                    .replace(error_string.lines().join(" "));
11954            }
11955        }
11956    }
11957
11958    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11959        self.lsp_server_capabilities.remove(&for_server);
11960        for lsp_data in self.lsp_data.values_mut() {
11961            lsp_data.remove_server_data(for_server);
11962        }
11963        if let Some(local) = self.as_local_mut() {
11964            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11965            local
11966                .workspace_pull_diagnostics_result_ids
11967                .remove(&for_server);
11968            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11969                buffer_servers.remove(&for_server);
11970            }
11971        }
11972    }
11973
11974    pub fn result_id_for_buffer_pull(
11975        &self,
11976        server_id: LanguageServerId,
11977        buffer_id: BufferId,
11978        registration_id: &Option<SharedString>,
11979        cx: &App,
11980    ) -> Option<SharedString> {
11981        let abs_path = self
11982            .buffer_store
11983            .read(cx)
11984            .get(buffer_id)
11985            .and_then(|b| File::from_dyn(b.read(cx).file()))
11986            .map(|f| f.abs_path(cx))?;
11987        self.as_local()?
11988            .buffer_pull_diagnostics_result_ids
11989            .get(&server_id)?
11990            .get(registration_id)?
11991            .get(&abs_path)?
11992            .clone()
11993    }
11994
11995    /// Gets all result_ids for a workspace diagnostics pull request.
11996    /// First, it tries to find buffer's result_id retrieved via the diagnostics pull; if it fails, it falls back to the workspace disagnostics pull result_id.
11997    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
11998    pub fn result_ids_for_workspace_refresh(
11999        &self,
12000        server_id: LanguageServerId,
12001        registration_id: &Option<SharedString>,
12002    ) -> HashMap<PathBuf, SharedString> {
12003        let Some(local) = self.as_local() else {
12004            return HashMap::default();
12005        };
12006        local
12007            .workspace_pull_diagnostics_result_ids
12008            .get(&server_id)
12009            .into_iter()
12010            .filter_map(|diagnostics| diagnostics.get(registration_id))
12011            .flatten()
12012            .filter_map(|(abs_path, result_id)| {
12013                let result_id = local
12014                    .buffer_pull_diagnostics_result_ids
12015                    .get(&server_id)
12016                    .and_then(|buffer_ids_result_ids| {
12017                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12018                    })
12019                    .cloned()
12020                    .flatten()
12021                    .or_else(|| result_id.clone())?;
12022                Some((abs_path.clone(), result_id))
12023            })
12024            .collect()
12025    }
12026
12027    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12028        if let Some(LanguageServerState::Running {
12029            workspace_diagnostics_refresh_tasks,
12030            ..
12031        }) = self
12032            .as_local_mut()
12033            .and_then(|local| local.language_servers.get_mut(&server_id))
12034        {
12035            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12036                diagnostics.refresh_tx.try_send(()).ok();
12037            }
12038        }
12039    }
12040
12041    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
12042        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
12043            return;
12044        };
12045        let Some(local) = self.as_local_mut() else {
12046            return;
12047        };
12048
12049        for server_id in buffer.update(cx, |buffer, cx| {
12050            local.language_server_ids_for_buffer(buffer, cx)
12051        }) {
12052            if let Some(LanguageServerState::Running {
12053                workspace_diagnostics_refresh_tasks,
12054                ..
12055            }) = local.language_servers.get_mut(&server_id)
12056            {
12057                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12058                    diagnostics.refresh_tx.try_send(()).ok();
12059                }
12060            }
12061        }
12062    }
12063
12064    fn apply_workspace_diagnostic_report(
12065        &mut self,
12066        server_id: LanguageServerId,
12067        report: lsp::WorkspaceDiagnosticReportResult,
12068        registration_id: Option<SharedString>,
12069        cx: &mut Context<Self>,
12070    ) {
12071        let workspace_diagnostics =
12072            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12073                report,
12074                server_id,
12075                registration_id,
12076            );
12077        let mut unchanged_buffers = HashMap::default();
12078        let workspace_diagnostics_updates = workspace_diagnostics
12079            .into_iter()
12080            .filter_map(
12081                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12082                    LspPullDiagnostics::Response {
12083                        server_id,
12084                        uri,
12085                        diagnostics,
12086                        registration_id,
12087                    } => Some((
12088                        server_id,
12089                        uri,
12090                        diagnostics,
12091                        workspace_diagnostics.version,
12092                        registration_id,
12093                    )),
12094                    LspPullDiagnostics::Default => None,
12095                },
12096            )
12097            .fold(
12098                HashMap::default(),
12099                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12100                    let (result_id, diagnostics) = match diagnostics {
12101                        PulledDiagnostics::Unchanged { result_id } => {
12102                            unchanged_buffers
12103                                .entry(new_registration_id.clone())
12104                                .or_insert_with(HashSet::default)
12105                                .insert(uri.clone());
12106                            (Some(result_id), Vec::new())
12107                        }
12108                        PulledDiagnostics::Changed {
12109                            result_id,
12110                            diagnostics,
12111                        } => (result_id, diagnostics),
12112                    };
12113                    let disk_based_sources = Cow::Owned(
12114                        self.language_server_adapter_for_id(server_id)
12115                            .as_ref()
12116                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12117                            .unwrap_or(&[])
12118                            .to_vec(),
12119                    );
12120
12121                    let Some(abs_path) = uri.to_file_path().ok() else {
12122                        return acc;
12123                    };
12124                    let Some((worktree, relative_path)) =
12125                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12126                    else {
12127                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12128                        return acc;
12129                    };
12130                    let worktree_id = worktree.read(cx).id();
12131                    let project_path = ProjectPath {
12132                        worktree_id,
12133                        path: relative_path,
12134                    };
12135                    if let Some(local_lsp_store) = self.as_local_mut() {
12136                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12137                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12138                    }
12139                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12140                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12141                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12142                        acc.entry(server_id)
12143                            .or_insert_with(HashMap::default)
12144                            .entry(new_registration_id.clone())
12145                            .or_insert_with(Vec::new)
12146                            .push(DocumentDiagnosticsUpdate {
12147                                server_id,
12148                                diagnostics: lsp::PublishDiagnosticsParams {
12149                                    uri,
12150                                    diagnostics,
12151                                    version,
12152                                },
12153                                result_id,
12154                                disk_based_sources,
12155                                registration_id: new_registration_id,
12156                            });
12157                    }
12158                    acc
12159                },
12160            );
12161
12162        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12163            for (registration_id, diagnostic_updates) in diagnostic_updates {
12164                self.merge_lsp_diagnostics(
12165                    DiagnosticSourceKind::Pulled,
12166                    diagnostic_updates,
12167                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12168                        DiagnosticSourceKind::Pulled => {
12169                            old_diagnostic.registration_id != registration_id
12170                                || unchanged_buffers
12171                                    .get(&old_diagnostic.registration_id)
12172                                    .is_some_and(|unchanged_buffers| {
12173                                        unchanged_buffers.contains(&document_uri)
12174                                    })
12175                        }
12176                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12177                    },
12178                    cx,
12179                )
12180                .log_err();
12181            }
12182        }
12183    }
12184
12185    fn register_server_capabilities(
12186        &mut self,
12187        server_id: LanguageServerId,
12188        params: lsp::RegistrationParams,
12189        cx: &mut Context<Self>,
12190    ) -> anyhow::Result<()> {
12191        let server = self
12192            .language_server_for_id(server_id)
12193            .with_context(|| format!("no server {server_id} found"))?;
12194        for reg in params.registrations {
12195            match reg.method.as_str() {
12196                "workspace/didChangeWatchedFiles" => {
12197                    if let Some(options) = reg.register_options {
12198                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12199                            let caps = serde_json::from_value(options)?;
12200                            local_lsp_store
12201                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12202                            true
12203                        } else {
12204                            false
12205                        };
12206                        if notify {
12207                            notify_server_capabilities_updated(&server, cx);
12208                        }
12209                    }
12210                }
12211                "workspace/didChangeConfiguration" => {
12212                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12213                }
12214                "workspace/didChangeWorkspaceFolders" => {
12215                    // In this case register options is an empty object, we can ignore it
12216                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12217                        supported: Some(true),
12218                        change_notifications: Some(OneOf::Right(reg.id)),
12219                    };
12220                    server.update_capabilities(|capabilities| {
12221                        capabilities
12222                            .workspace
12223                            .get_or_insert_default()
12224                            .workspace_folders = Some(caps);
12225                    });
12226                    notify_server_capabilities_updated(&server, cx);
12227                }
12228                "workspace/symbol" => {
12229                    let options = parse_register_capabilities(reg)?;
12230                    server.update_capabilities(|capabilities| {
12231                        capabilities.workspace_symbol_provider = Some(options);
12232                    });
12233                    notify_server_capabilities_updated(&server, cx);
12234                }
12235                "workspace/fileOperations" => {
12236                    if let Some(options) = reg.register_options {
12237                        let caps = serde_json::from_value(options)?;
12238                        server.update_capabilities(|capabilities| {
12239                            capabilities
12240                                .workspace
12241                                .get_or_insert_default()
12242                                .file_operations = Some(caps);
12243                        });
12244                        notify_server_capabilities_updated(&server, cx);
12245                    }
12246                }
12247                "workspace/executeCommand" => {
12248                    if let Some(options) = reg.register_options {
12249                        let options = serde_json::from_value(options)?;
12250                        server.update_capabilities(|capabilities| {
12251                            capabilities.execute_command_provider = Some(options);
12252                        });
12253                        notify_server_capabilities_updated(&server, cx);
12254                    }
12255                }
12256                "textDocument/rangeFormatting" => {
12257                    let options = parse_register_capabilities(reg)?;
12258                    server.update_capabilities(|capabilities| {
12259                        capabilities.document_range_formatting_provider = Some(options);
12260                    });
12261                    notify_server_capabilities_updated(&server, cx);
12262                }
12263                "textDocument/onTypeFormatting" => {
12264                    if let Some(options) = reg
12265                        .register_options
12266                        .map(serde_json::from_value)
12267                        .transpose()?
12268                    {
12269                        server.update_capabilities(|capabilities| {
12270                            capabilities.document_on_type_formatting_provider = Some(options);
12271                        });
12272                        notify_server_capabilities_updated(&server, cx);
12273                    }
12274                }
12275                "textDocument/formatting" => {
12276                    let options = parse_register_capabilities(reg)?;
12277                    server.update_capabilities(|capabilities| {
12278                        capabilities.document_formatting_provider = Some(options);
12279                    });
12280                    notify_server_capabilities_updated(&server, cx);
12281                }
12282                "textDocument/rename" => {
12283                    let options = parse_register_capabilities(reg)?;
12284                    server.update_capabilities(|capabilities| {
12285                        capabilities.rename_provider = Some(options);
12286                    });
12287                    notify_server_capabilities_updated(&server, cx);
12288                }
12289                "textDocument/inlayHint" => {
12290                    let options = parse_register_capabilities(reg)?;
12291                    server.update_capabilities(|capabilities| {
12292                        capabilities.inlay_hint_provider = Some(options);
12293                    });
12294                    notify_server_capabilities_updated(&server, cx);
12295                }
12296                "textDocument/documentSymbol" => {
12297                    let options = parse_register_capabilities(reg)?;
12298                    server.update_capabilities(|capabilities| {
12299                        capabilities.document_symbol_provider = Some(options);
12300                    });
12301                    notify_server_capabilities_updated(&server, cx);
12302                }
12303                "textDocument/codeAction" => {
12304                    let options = parse_register_capabilities(reg)?;
12305                    let provider = match options {
12306                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12307                        OneOf::Right(caps) => caps,
12308                    };
12309                    server.update_capabilities(|capabilities| {
12310                        capabilities.code_action_provider = Some(provider);
12311                    });
12312                    notify_server_capabilities_updated(&server, cx);
12313                }
12314                "textDocument/definition" => {
12315                    let options = parse_register_capabilities(reg)?;
12316                    server.update_capabilities(|capabilities| {
12317                        capabilities.definition_provider = Some(options);
12318                    });
12319                    notify_server_capabilities_updated(&server, cx);
12320                }
12321                "textDocument/completion" => {
12322                    if let Some(caps) = reg
12323                        .register_options
12324                        .map(serde_json::from_value::<CompletionOptions>)
12325                        .transpose()?
12326                    {
12327                        server.update_capabilities(|capabilities| {
12328                            capabilities.completion_provider = Some(caps.clone());
12329                        });
12330
12331                        if let Some(local) = self.as_local() {
12332                            let mut buffers_with_language_server = Vec::new();
12333                            for handle in self.buffer_store.read(cx).buffers() {
12334                                let buffer_id = handle.read(cx).remote_id();
12335                                if local
12336                                    .buffers_opened_in_servers
12337                                    .get(&buffer_id)
12338                                    .filter(|s| s.contains(&server_id))
12339                                    .is_some()
12340                                {
12341                                    buffers_with_language_server.push(handle);
12342                                }
12343                            }
12344                            let triggers = caps
12345                                .trigger_characters
12346                                .unwrap_or_default()
12347                                .into_iter()
12348                                .collect::<BTreeSet<_>>();
12349                            for handle in buffers_with_language_server {
12350                                let triggers = triggers.clone();
12351                                let _ = handle.update(cx, move |buffer, cx| {
12352                                    buffer.set_completion_triggers(server_id, triggers, cx);
12353                                });
12354                            }
12355                        }
12356                        notify_server_capabilities_updated(&server, cx);
12357                    }
12358                }
12359                "textDocument/hover" => {
12360                    let options = parse_register_capabilities(reg)?;
12361                    let provider = match options {
12362                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12363                        OneOf::Right(caps) => caps,
12364                    };
12365                    server.update_capabilities(|capabilities| {
12366                        capabilities.hover_provider = Some(provider);
12367                    });
12368                    notify_server_capabilities_updated(&server, cx);
12369                }
12370                "textDocument/signatureHelp" => {
12371                    if let Some(caps) = reg
12372                        .register_options
12373                        .map(serde_json::from_value)
12374                        .transpose()?
12375                    {
12376                        server.update_capabilities(|capabilities| {
12377                            capabilities.signature_help_provider = Some(caps);
12378                        });
12379                        notify_server_capabilities_updated(&server, cx);
12380                    }
12381                }
12382                "textDocument/didChange" => {
12383                    if let Some(sync_kind) = reg
12384                        .register_options
12385                        .and_then(|opts| opts.get("syncKind").cloned())
12386                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12387                        .transpose()?
12388                    {
12389                        server.update_capabilities(|capabilities| {
12390                            let mut sync_options =
12391                                Self::take_text_document_sync_options(capabilities);
12392                            sync_options.change = Some(sync_kind);
12393                            capabilities.text_document_sync =
12394                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12395                        });
12396                        notify_server_capabilities_updated(&server, cx);
12397                    }
12398                }
12399                "textDocument/didSave" => {
12400                    if let Some(include_text) = reg
12401                        .register_options
12402                        .map(|opts| {
12403                            let transpose = opts
12404                                .get("includeText")
12405                                .cloned()
12406                                .map(serde_json::from_value::<Option<bool>>)
12407                                .transpose();
12408                            match transpose {
12409                                Ok(value) => Ok(value.flatten()),
12410                                Err(e) => Err(e),
12411                            }
12412                        })
12413                        .transpose()?
12414                    {
12415                        server.update_capabilities(|capabilities| {
12416                            let mut sync_options =
12417                                Self::take_text_document_sync_options(capabilities);
12418                            sync_options.save =
12419                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12420                                    include_text,
12421                                }));
12422                            capabilities.text_document_sync =
12423                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12424                        });
12425                        notify_server_capabilities_updated(&server, cx);
12426                    }
12427                }
12428                "textDocument/codeLens" => {
12429                    if let Some(caps) = reg
12430                        .register_options
12431                        .map(serde_json::from_value)
12432                        .transpose()?
12433                    {
12434                        server.update_capabilities(|capabilities| {
12435                            capabilities.code_lens_provider = Some(caps);
12436                        });
12437                        notify_server_capabilities_updated(&server, cx);
12438                    }
12439                }
12440                "textDocument/diagnostic" => {
12441                    if let Some(caps) = reg
12442                        .register_options
12443                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12444                        .transpose()?
12445                    {
12446                        let local = self
12447                            .as_local_mut()
12448                            .context("Expected LSP Store to be local")?;
12449                        let state = local
12450                            .language_servers
12451                            .get_mut(&server_id)
12452                            .context("Could not obtain Language Servers state")?;
12453                        local
12454                            .language_server_dynamic_registrations
12455                            .entry(server_id)
12456                            .or_default()
12457                            .diagnostics
12458                            .insert(Some(reg.id.clone()), caps.clone());
12459
12460                        let supports_workspace_diagnostics =
12461                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12462                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12463                                    diagnostic_options.workspace_diagnostics
12464                                }
12465                                DiagnosticServerCapabilities::RegistrationOptions(
12466                                    diagnostic_registration_options,
12467                                ) => {
12468                                    diagnostic_registration_options
12469                                        .diagnostic_options
12470                                        .workspace_diagnostics
12471                                }
12472                            };
12473
12474                        if supports_workspace_diagnostics(&caps) {
12475                            if let LanguageServerState::Running {
12476                                workspace_diagnostics_refresh_tasks,
12477                                ..
12478                            } = state
12479                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12480                                    Some(reg.id.clone()),
12481                                    caps.clone(),
12482                                    server.clone(),
12483                                    cx,
12484                                )
12485                            {
12486                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12487                            }
12488                        }
12489
12490                        server.update_capabilities(|capabilities| {
12491                            capabilities.diagnostic_provider = Some(caps);
12492                        });
12493
12494                        notify_server_capabilities_updated(&server, cx);
12495                    }
12496                }
12497                "textDocument/documentColor" => {
12498                    let options = parse_register_capabilities(reg)?;
12499                    let provider = match options {
12500                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12501                        OneOf::Right(caps) => caps,
12502                    };
12503                    server.update_capabilities(|capabilities| {
12504                        capabilities.color_provider = Some(provider);
12505                    });
12506                    notify_server_capabilities_updated(&server, cx);
12507                }
12508                _ => log::warn!("unhandled capability registration: {reg:?}"),
12509            }
12510        }
12511
12512        Ok(())
12513    }
12514
12515    fn unregister_server_capabilities(
12516        &mut self,
12517        server_id: LanguageServerId,
12518        params: lsp::UnregistrationParams,
12519        cx: &mut Context<Self>,
12520    ) -> anyhow::Result<()> {
12521        let server = self
12522            .language_server_for_id(server_id)
12523            .with_context(|| format!("no server {server_id} found"))?;
12524        for unreg in params.unregisterations.iter() {
12525            match unreg.method.as_str() {
12526                "workspace/didChangeWatchedFiles" => {
12527                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12528                        local_lsp_store
12529                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12530                        true
12531                    } else {
12532                        false
12533                    };
12534                    if notify {
12535                        notify_server_capabilities_updated(&server, cx);
12536                    }
12537                }
12538                "workspace/didChangeConfiguration" => {
12539                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12540                }
12541                "workspace/didChangeWorkspaceFolders" => {
12542                    server.update_capabilities(|capabilities| {
12543                        capabilities
12544                            .workspace
12545                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12546                                workspace_folders: None,
12547                                file_operations: None,
12548                            })
12549                            .workspace_folders = None;
12550                    });
12551                    notify_server_capabilities_updated(&server, cx);
12552                }
12553                "workspace/symbol" => {
12554                    server.update_capabilities(|capabilities| {
12555                        capabilities.workspace_symbol_provider = None
12556                    });
12557                    notify_server_capabilities_updated(&server, cx);
12558                }
12559                "workspace/fileOperations" => {
12560                    server.update_capabilities(|capabilities| {
12561                        capabilities
12562                            .workspace
12563                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12564                                workspace_folders: None,
12565                                file_operations: None,
12566                            })
12567                            .file_operations = None;
12568                    });
12569                    notify_server_capabilities_updated(&server, cx);
12570                }
12571                "workspace/executeCommand" => {
12572                    server.update_capabilities(|capabilities| {
12573                        capabilities.execute_command_provider = None;
12574                    });
12575                    notify_server_capabilities_updated(&server, cx);
12576                }
12577                "textDocument/rangeFormatting" => {
12578                    server.update_capabilities(|capabilities| {
12579                        capabilities.document_range_formatting_provider = None
12580                    });
12581                    notify_server_capabilities_updated(&server, cx);
12582                }
12583                "textDocument/onTypeFormatting" => {
12584                    server.update_capabilities(|capabilities| {
12585                        capabilities.document_on_type_formatting_provider = None;
12586                    });
12587                    notify_server_capabilities_updated(&server, cx);
12588                }
12589                "textDocument/formatting" => {
12590                    server.update_capabilities(|capabilities| {
12591                        capabilities.document_formatting_provider = None;
12592                    });
12593                    notify_server_capabilities_updated(&server, cx);
12594                }
12595                "textDocument/rename" => {
12596                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12597                    notify_server_capabilities_updated(&server, cx);
12598                }
12599                "textDocument/codeAction" => {
12600                    server.update_capabilities(|capabilities| {
12601                        capabilities.code_action_provider = None;
12602                    });
12603                    notify_server_capabilities_updated(&server, cx);
12604                }
12605                "textDocument/definition" => {
12606                    server.update_capabilities(|capabilities| {
12607                        capabilities.definition_provider = None;
12608                    });
12609                    notify_server_capabilities_updated(&server, cx);
12610                }
12611                "textDocument/completion" => {
12612                    server.update_capabilities(|capabilities| {
12613                        capabilities.completion_provider = None;
12614                    });
12615                    notify_server_capabilities_updated(&server, cx);
12616                }
12617                "textDocument/hover" => {
12618                    server.update_capabilities(|capabilities| {
12619                        capabilities.hover_provider = None;
12620                    });
12621                    notify_server_capabilities_updated(&server, cx);
12622                }
12623                "textDocument/signatureHelp" => {
12624                    server.update_capabilities(|capabilities| {
12625                        capabilities.signature_help_provider = None;
12626                    });
12627                    notify_server_capabilities_updated(&server, cx);
12628                }
12629                "textDocument/didChange" => {
12630                    server.update_capabilities(|capabilities| {
12631                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12632                        sync_options.change = None;
12633                        capabilities.text_document_sync =
12634                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12635                    });
12636                    notify_server_capabilities_updated(&server, cx);
12637                }
12638                "textDocument/didSave" => {
12639                    server.update_capabilities(|capabilities| {
12640                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12641                        sync_options.save = None;
12642                        capabilities.text_document_sync =
12643                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12644                    });
12645                    notify_server_capabilities_updated(&server, cx);
12646                }
12647                "textDocument/codeLens" => {
12648                    server.update_capabilities(|capabilities| {
12649                        capabilities.code_lens_provider = None;
12650                    });
12651                    notify_server_capabilities_updated(&server, cx);
12652                }
12653                "textDocument/diagnostic" => {
12654                    let local = self
12655                        .as_local_mut()
12656                        .context("Expected LSP Store to be local")?;
12657
12658                    let state = local
12659                        .language_servers
12660                        .get_mut(&server_id)
12661                        .context("Could not obtain Language Servers state")?;
12662                    let registrations = local
12663                        .language_server_dynamic_registrations
12664                        .get_mut(&server_id)
12665                        .with_context(|| {
12666                            format!("Expected dynamic registration to exist for server {server_id}")
12667                        })?;
12668                    registrations.diagnostics
12669                        .remove(&Some(unreg.id.clone()))
12670                        .with_context(|| format!(
12671                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12672                            unreg.id)
12673                        )?;
12674                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12675
12676                    if let LanguageServerState::Running {
12677                        workspace_diagnostics_refresh_tasks,
12678                        ..
12679                    } = state
12680                    {
12681                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12682                    }
12683
12684                    if removed_last_diagnostic_provider {
12685                        server.update_capabilities(|capabilities| {
12686                            debug_assert!(capabilities.diagnostic_provider.is_some());
12687                            capabilities.diagnostic_provider = None;
12688                        });
12689                    }
12690
12691                    notify_server_capabilities_updated(&server, cx);
12692                }
12693                "textDocument/documentColor" => {
12694                    server.update_capabilities(|capabilities| {
12695                        capabilities.color_provider = None;
12696                    });
12697                    notify_server_capabilities_updated(&server, cx);
12698                }
12699                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12700            }
12701        }
12702
12703        Ok(())
12704    }
12705
12706    async fn deduplicate_range_based_lsp_requests<T>(
12707        lsp_store: &Entity<Self>,
12708        server_id: Option<LanguageServerId>,
12709        lsp_request_id: LspRequestId,
12710        proto_request: &T::ProtoRequest,
12711        range: Range<Anchor>,
12712        cx: &mut AsyncApp,
12713    ) -> Result<()>
12714    where
12715        T: LspCommand,
12716        T::ProtoRequest: proto::LspRequestMessage,
12717    {
12718        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12719        let version = deserialize_version(proto_request.buffer_version());
12720        let buffer = lsp_store.update(cx, |this, cx| {
12721            this.buffer_store.read(cx).get_existing(buffer_id)
12722        })??;
12723        buffer
12724            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12725            .await?;
12726        lsp_store.update(cx, |lsp_store, cx| {
12727            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12728            let chunks_queried_for = lsp_data
12729                .inlay_hints
12730                .applicable_chunks(&[range])
12731                .collect::<Vec<_>>();
12732            match chunks_queried_for.as_slice() {
12733                &[chunk] => {
12734                    let key = LspKey {
12735                        request_type: TypeId::of::<T>(),
12736                        server_queried: server_id,
12737                    };
12738                    let previous_request = lsp_data
12739                        .chunk_lsp_requests
12740                        .entry(key)
12741                        .or_default()
12742                        .insert(chunk, lsp_request_id);
12743                    if let Some((previous_request, running_requests)) =
12744                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12745                    {
12746                        running_requests.remove(&previous_request);
12747                    }
12748                }
12749                _ambiguous_chunks => {
12750                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12751                    // there, a buffer version-based check will be performed and outdated requests discarded.
12752                }
12753            }
12754            anyhow::Ok(())
12755        })??;
12756
12757        Ok(())
12758    }
12759
12760    async fn query_lsp_locally<T>(
12761        lsp_store: Entity<Self>,
12762        for_server_id: Option<LanguageServerId>,
12763        sender_id: proto::PeerId,
12764        lsp_request_id: LspRequestId,
12765        proto_request: T::ProtoRequest,
12766        position: Option<Anchor>,
12767        cx: &mut AsyncApp,
12768    ) -> Result<()>
12769    where
12770        T: LspCommand + Clone,
12771        T::ProtoRequest: proto::LspRequestMessage,
12772        <T::ProtoRequest as proto::RequestMessage>::Response:
12773            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12774    {
12775        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12776        let version = deserialize_version(proto_request.buffer_version());
12777        let buffer = lsp_store.update(cx, |this, cx| {
12778            this.buffer_store.read(cx).get_existing(buffer_id)
12779        })??;
12780        buffer
12781            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12782            .await?;
12783        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12784        let request =
12785            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12786        let key = LspKey {
12787            request_type: TypeId::of::<T>(),
12788            server_queried: for_server_id,
12789        };
12790        lsp_store.update(cx, |lsp_store, cx| {
12791            let request_task = match for_server_id {
12792                Some(server_id) => {
12793                    let server_task = lsp_store.request_lsp(
12794                        buffer.clone(),
12795                        LanguageServerToQuery::Other(server_id),
12796                        request.clone(),
12797                        cx,
12798                    );
12799                    cx.background_spawn(async move {
12800                        let mut responses = Vec::new();
12801                        match server_task.await {
12802                            Ok(response) => responses.push((server_id, response)),
12803                            // rust-analyzer likes to error with this when its still loading up
12804                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12805                            Err(e) => log::error!(
12806                                "Error handling response for request {request:?}: {e:#}"
12807                            ),
12808                        }
12809                        responses
12810                    })
12811                }
12812                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12813            };
12814            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12815            if T::ProtoRequest::stop_previous_requests() {
12816                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12817                    lsp_requests.clear();
12818                }
12819            }
12820            lsp_data.lsp_requests.entry(key).or_default().insert(
12821                lsp_request_id,
12822                cx.spawn(async move |lsp_store, cx| {
12823                    let response = request_task.await;
12824                    lsp_store
12825                        .update(cx, |lsp_store, cx| {
12826                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12827                            {
12828                                let response = response
12829                                    .into_iter()
12830                                    .map(|(server_id, response)| {
12831                                        (
12832                                            server_id.to_proto(),
12833                                            T::response_to_proto(
12834                                                response,
12835                                                lsp_store,
12836                                                sender_id,
12837                                                &buffer_version,
12838                                                cx,
12839                                            )
12840                                            .into(),
12841                                        )
12842                                    })
12843                                    .collect::<HashMap<_, _>>();
12844                                match client.send_lsp_response::<T::ProtoRequest>(
12845                                    project_id,
12846                                    lsp_request_id,
12847                                    response,
12848                                ) {
12849                                    Ok(()) => {}
12850                                    Err(e) => {
12851                                        log::error!("Failed to send LSP response: {e:#}",)
12852                                    }
12853                                }
12854                            }
12855                        })
12856                        .ok();
12857                }),
12858            );
12859        })?;
12860        Ok(())
12861    }
12862
12863    fn take_text_document_sync_options(
12864        capabilities: &mut lsp::ServerCapabilities,
12865    ) -> lsp::TextDocumentSyncOptions {
12866        match capabilities.text_document_sync.take() {
12867            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12868            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12869                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12870                sync_options.change = Some(sync_kind);
12871                sync_options
12872            }
12873            None => lsp::TextDocumentSyncOptions::default(),
12874        }
12875    }
12876
12877    #[cfg(any(test, feature = "test-support"))]
12878    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12879        Some(
12880            self.lsp_data
12881                .get_mut(&buffer_id)?
12882                .code_lens
12883                .take()?
12884                .update
12885                .take()?
12886                .1,
12887        )
12888    }
12889
12890    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12891        self.downstream_client.clone()
12892    }
12893
12894    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12895        self.worktree_store.clone()
12896    }
12897
12898    /// Gets what's stored in the LSP data for the given buffer.
12899    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12900        self.lsp_data.get_mut(&buffer_id)
12901    }
12902
12903    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12904    /// new [`BufferLspData`] will be created to replace the previous state.
12905    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12906        let (buffer_id, buffer_version) =
12907            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12908        let lsp_data = self
12909            .lsp_data
12910            .entry(buffer_id)
12911            .or_insert_with(|| BufferLspData::new(buffer, cx));
12912        if buffer_version.changed_since(&lsp_data.buffer_version) {
12913            *lsp_data = BufferLspData::new(buffer, cx);
12914        }
12915        lsp_data
12916    }
12917}
12918
12919// Registration with registerOptions as null, should fallback to true.
12920// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12921fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12922    reg: lsp::Registration,
12923) -> Result<OneOf<bool, T>> {
12924    Ok(match reg.register_options {
12925        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12926        None => OneOf::Left(true),
12927    })
12928}
12929
12930fn subscribe_to_binary_statuses(
12931    languages: &Arc<LanguageRegistry>,
12932    cx: &mut Context<'_, LspStore>,
12933) -> Task<()> {
12934    let mut server_statuses = languages.language_server_binary_statuses();
12935    cx.spawn(async move |lsp_store, cx| {
12936        while let Some((server_name, binary_status)) = server_statuses.next().await {
12937            if lsp_store
12938                .update(cx, |_, cx| {
12939                    let mut message = None;
12940                    let binary_status = match binary_status {
12941                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12942                        BinaryStatus::CheckingForUpdate => {
12943                            proto::ServerBinaryStatus::CheckingForUpdate
12944                        }
12945                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12946                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12947                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12948                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12949                        BinaryStatus::Failed { error } => {
12950                            message = Some(error);
12951                            proto::ServerBinaryStatus::Failed
12952                        }
12953                    };
12954                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12955                        // Binary updates are about the binary that might not have any language server id at that point.
12956                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12957                        language_server_id: LanguageServerId(0),
12958                        name: Some(server_name),
12959                        message: proto::update_language_server::Variant::StatusUpdate(
12960                            proto::StatusUpdate {
12961                                message,
12962                                status: Some(proto::status_update::Status::Binary(
12963                                    binary_status as i32,
12964                                )),
12965                            },
12966                        ),
12967                    });
12968                })
12969                .is_err()
12970            {
12971                break;
12972            }
12973        }
12974    })
12975}
12976
12977fn lsp_workspace_diagnostics_refresh(
12978    registration_id: Option<String>,
12979    options: DiagnosticServerCapabilities,
12980    server: Arc<LanguageServer>,
12981    cx: &mut Context<'_, LspStore>,
12982) -> Option<WorkspaceRefreshTask> {
12983    let identifier = workspace_diagnostic_identifier(&options)?;
12984    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
12985
12986    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12987    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12988    refresh_tx.try_send(()).ok();
12989
12990    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12991        let mut attempts = 0;
12992        let max_attempts = 50;
12993        let mut requests = 0;
12994
12995        loop {
12996            let Some(()) = refresh_rx.recv().await else {
12997                return;
12998            };
12999
13000            'request: loop {
13001                requests += 1;
13002                if attempts > max_attempts {
13003                    log::error!(
13004                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13005                    );
13006                    return;
13007                }
13008                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13009                cx.background_executor()
13010                    .timer(Duration::from_millis(backoff_millis))
13011                    .await;
13012                attempts += 1;
13013
13014                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13015                    lsp_store
13016                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13017                        .into_iter()
13018                        .filter_map(|(abs_path, result_id)| {
13019                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13020                            Some(lsp::PreviousResultId {
13021                                uri,
13022                                value: result_id.to_string(),
13023                            })
13024                        })
13025                        .collect()
13026                }) else {
13027                    return;
13028                };
13029
13030                let token = if let Some(registration_id) = &registration_id {
13031                    format!(
13032                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13033                        server.server_id(),
13034                    )
13035                } else {
13036                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13037                };
13038
13039                progress_rx.try_recv().ok();
13040                let timer =
13041                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13042                let progress = pin!(progress_rx.recv().fuse());
13043                let response_result = server
13044                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13045                        lsp::WorkspaceDiagnosticParams {
13046                            previous_result_ids,
13047                            identifier: identifier.clone(),
13048                            work_done_progress_params: Default::default(),
13049                            partial_result_params: lsp::PartialResultParams {
13050                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13051                            },
13052                        },
13053                        select(timer, progress).then(|either| match either {
13054                            Either::Left((message, ..)) => ready(message).left_future(),
13055                            Either::Right(..) => pending::<String>().right_future(),
13056                        }),
13057                    )
13058                    .await;
13059
13060                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13061                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13062                match response_result {
13063                    ConnectionResult::Timeout => {
13064                        log::error!("Timeout during workspace diagnostics pull");
13065                        continue 'request;
13066                    }
13067                    ConnectionResult::ConnectionReset => {
13068                        log::error!("Server closed a workspace diagnostics pull request");
13069                        continue 'request;
13070                    }
13071                    ConnectionResult::Result(Err(e)) => {
13072                        log::error!("Error during workspace diagnostics pull: {e:#}");
13073                        break 'request;
13074                    }
13075                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13076                        attempts = 0;
13077                        if lsp_store
13078                            .update(cx, |lsp_store, cx| {
13079                                lsp_store.apply_workspace_diagnostic_report(
13080                                    server.server_id(),
13081                                    pulled_diagnostics,
13082                                    registration_id_shared.clone(),
13083                                    cx,
13084                                )
13085                            })
13086                            .is_err()
13087                        {
13088                            return;
13089                        }
13090                        break 'request;
13091                    }
13092                }
13093            }
13094        }
13095    });
13096
13097    Some(WorkspaceRefreshTask {
13098        refresh_tx,
13099        progress_tx,
13100        task: workspace_query_language_server,
13101    })
13102}
13103
13104fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13105    match &options {
13106        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13107            diagnostic_options.identifier.clone()
13108        }
13109        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13110            let diagnostic_options = &registration_options.diagnostic_options;
13111            diagnostic_options.identifier.clone()
13112        }
13113    }
13114}
13115
13116fn workspace_diagnostic_identifier(
13117    options: &DiagnosticServerCapabilities,
13118) -> Option<Option<String>> {
13119    match &options {
13120        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13121            if !diagnostic_options.workspace_diagnostics {
13122                return None;
13123            }
13124            Some(diagnostic_options.identifier.clone())
13125        }
13126        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13127            let diagnostic_options = &registration_options.diagnostic_options;
13128            if !diagnostic_options.workspace_diagnostics {
13129                return None;
13130            }
13131            Some(diagnostic_options.identifier.clone())
13132        }
13133    }
13134}
13135
13136fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13137    let CompletionSource::BufferWord {
13138        word_range,
13139        resolved,
13140    } = &mut completion.source
13141    else {
13142        return;
13143    };
13144    if *resolved {
13145        return;
13146    }
13147
13148    if completion.new_text
13149        != snapshot
13150            .text_for_range(word_range.clone())
13151            .collect::<String>()
13152    {
13153        return;
13154    }
13155
13156    let mut offset = 0;
13157    for chunk in snapshot.chunks(word_range.clone(), true) {
13158        let end_offset = offset + chunk.text.len();
13159        if let Some(highlight_id) = chunk.syntax_highlight_id {
13160            completion
13161                .label
13162                .runs
13163                .push((offset..end_offset, highlight_id));
13164        }
13165        offset = end_offset;
13166    }
13167    *resolved = true;
13168}
13169
13170impl EventEmitter<LspStoreEvent> for LspStore {}
13171
13172fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13173    hover
13174        .contents
13175        .retain(|hover_block| !hover_block.text.trim().is_empty());
13176    if hover.contents.is_empty() {
13177        None
13178    } else {
13179        Some(hover)
13180    }
13181}
13182
13183async fn populate_labels_for_completions(
13184    new_completions: Vec<CoreCompletion>,
13185    language: Option<Arc<Language>>,
13186    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13187) -> Vec<Completion> {
13188    let lsp_completions = new_completions
13189        .iter()
13190        .filter_map(|new_completion| {
13191            new_completion
13192                .source
13193                .lsp_completion(true)
13194                .map(|lsp_completion| lsp_completion.into_owned())
13195        })
13196        .collect::<Vec<_>>();
13197
13198    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13199        lsp_adapter
13200            .labels_for_completions(&lsp_completions, language)
13201            .await
13202            .log_err()
13203            .unwrap_or_default()
13204    } else {
13205        Vec::new()
13206    }
13207    .into_iter()
13208    .fuse();
13209
13210    let mut completions = Vec::new();
13211    for completion in new_completions {
13212        match completion.source.lsp_completion(true) {
13213            Some(lsp_completion) => {
13214                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13215
13216                let mut label = labels.next().flatten().unwrap_or_else(|| {
13217                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13218                });
13219                ensure_uniform_list_compatible_label(&mut label);
13220                completions.push(Completion {
13221                    label,
13222                    documentation,
13223                    replace_range: completion.replace_range,
13224                    new_text: completion.new_text,
13225                    insert_text_mode: lsp_completion.insert_text_mode,
13226                    source: completion.source,
13227                    icon_path: None,
13228                    confirm: None,
13229                    match_start: None,
13230                    snippet_deduplication_key: None,
13231                });
13232            }
13233            None => {
13234                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13235                ensure_uniform_list_compatible_label(&mut label);
13236                completions.push(Completion {
13237                    label,
13238                    documentation: None,
13239                    replace_range: completion.replace_range,
13240                    new_text: completion.new_text,
13241                    source: completion.source,
13242                    insert_text_mode: None,
13243                    icon_path: None,
13244                    confirm: None,
13245                    match_start: None,
13246                    snippet_deduplication_key: None,
13247                });
13248            }
13249        }
13250    }
13251    completions
13252}
13253
13254#[derive(Debug)]
13255pub enum LanguageServerToQuery {
13256    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13257    FirstCapable,
13258    /// Query a specific language server.
13259    Other(LanguageServerId),
13260}
13261
13262#[derive(Default)]
13263struct RenamePathsWatchedForServer {
13264    did_rename: Vec<RenameActionPredicate>,
13265    will_rename: Vec<RenameActionPredicate>,
13266}
13267
13268impl RenamePathsWatchedForServer {
13269    fn with_did_rename_patterns(
13270        mut self,
13271        did_rename: Option<&FileOperationRegistrationOptions>,
13272    ) -> Self {
13273        if let Some(did_rename) = did_rename {
13274            self.did_rename = did_rename
13275                .filters
13276                .iter()
13277                .filter_map(|filter| filter.try_into().log_err())
13278                .collect();
13279        }
13280        self
13281    }
13282    fn with_will_rename_patterns(
13283        mut self,
13284        will_rename: Option<&FileOperationRegistrationOptions>,
13285    ) -> Self {
13286        if let Some(will_rename) = will_rename {
13287            self.will_rename = will_rename
13288                .filters
13289                .iter()
13290                .filter_map(|filter| filter.try_into().log_err())
13291                .collect();
13292        }
13293        self
13294    }
13295
13296    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13297        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13298    }
13299    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13300        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13301    }
13302}
13303
13304impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13305    type Error = globset::Error;
13306    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13307        Ok(Self {
13308            kind: ops.pattern.matches.clone(),
13309            glob: GlobBuilder::new(&ops.pattern.glob)
13310                .case_insensitive(
13311                    ops.pattern
13312                        .options
13313                        .as_ref()
13314                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13315                )
13316                .build()?
13317                .compile_matcher(),
13318        })
13319    }
13320}
13321struct RenameActionPredicate {
13322    glob: GlobMatcher,
13323    kind: Option<FileOperationPatternKind>,
13324}
13325
13326impl RenameActionPredicate {
13327    // Returns true if language server should be notified
13328    fn eval(&self, path: &str, is_dir: bool) -> bool {
13329        self.kind.as_ref().is_none_or(|kind| {
13330            let expected_kind = if is_dir {
13331                FileOperationPatternKind::Folder
13332            } else {
13333                FileOperationPatternKind::File
13334            };
13335            kind == &expected_kind
13336        }) && self.glob.is_match(path)
13337    }
13338}
13339
13340#[derive(Default)]
13341struct LanguageServerWatchedPaths {
13342    worktree_paths: HashMap<WorktreeId, GlobSet>,
13343    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13344}
13345
13346#[derive(Default)]
13347struct LanguageServerWatchedPathsBuilder {
13348    worktree_paths: HashMap<WorktreeId, GlobSet>,
13349    abs_paths: HashMap<Arc<Path>, GlobSet>,
13350}
13351
13352impl LanguageServerWatchedPathsBuilder {
13353    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13354        self.worktree_paths.insert(worktree_id, glob_set);
13355    }
13356    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13357        self.abs_paths.insert(path, glob_set);
13358    }
13359    fn build(
13360        self,
13361        fs: Arc<dyn Fs>,
13362        language_server_id: LanguageServerId,
13363        cx: &mut Context<LspStore>,
13364    ) -> LanguageServerWatchedPaths {
13365        let lsp_store = cx.weak_entity();
13366
13367        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13368        let abs_paths = self
13369            .abs_paths
13370            .into_iter()
13371            .map(|(abs_path, globset)| {
13372                let task = cx.spawn({
13373                    let abs_path = abs_path.clone();
13374                    let fs = fs.clone();
13375
13376                    let lsp_store = lsp_store.clone();
13377                    async move |_, cx| {
13378                        maybe!(async move {
13379                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13380                            while let Some(update) = push_updates.0.next().await {
13381                                let action = lsp_store
13382                                    .update(cx, |this, _| {
13383                                        let Some(local) = this.as_local() else {
13384                                            return ControlFlow::Break(());
13385                                        };
13386                                        let Some(watcher) = local
13387                                            .language_server_watched_paths
13388                                            .get(&language_server_id)
13389                                        else {
13390                                            return ControlFlow::Break(());
13391                                        };
13392                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13393                                            "Watched abs path is not registered with a watcher",
13394                                        );
13395                                        let matching_entries = update
13396                                            .into_iter()
13397                                            .filter(|event| globs.is_match(&event.path))
13398                                            .collect::<Vec<_>>();
13399                                        this.lsp_notify_abs_paths_changed(
13400                                            language_server_id,
13401                                            matching_entries,
13402                                        );
13403                                        ControlFlow::Continue(())
13404                                    })
13405                                    .ok()?;
13406
13407                                if action.is_break() {
13408                                    break;
13409                                }
13410                            }
13411                            Some(())
13412                        })
13413                        .await;
13414                    }
13415                });
13416                (abs_path, (globset, task))
13417            })
13418            .collect();
13419        LanguageServerWatchedPaths {
13420            worktree_paths: self.worktree_paths,
13421            abs_paths,
13422        }
13423    }
13424}
13425
13426struct LspBufferSnapshot {
13427    version: i32,
13428    snapshot: TextBufferSnapshot,
13429}
13430
13431/// A prompt requested by LSP server.
13432#[derive(Clone, Debug)]
13433pub struct LanguageServerPromptRequest {
13434    pub level: PromptLevel,
13435    pub message: String,
13436    pub actions: Vec<MessageActionItem>,
13437    pub lsp_name: String,
13438    pub(crate) response_channel: Sender<MessageActionItem>,
13439}
13440
13441impl LanguageServerPromptRequest {
13442    pub async fn respond(self, index: usize) -> Option<()> {
13443        if let Some(response) = self.actions.into_iter().nth(index) {
13444            self.response_channel.send(response).await.ok()
13445        } else {
13446            None
13447        }
13448    }
13449}
13450impl PartialEq for LanguageServerPromptRequest {
13451    fn eq(&self, other: &Self) -> bool {
13452        self.message == other.message && self.actions == other.actions
13453    }
13454}
13455
13456#[derive(Clone, Debug, PartialEq)]
13457pub enum LanguageServerLogType {
13458    Log(MessageType),
13459    Trace { verbose_info: Option<String> },
13460    Rpc { received: bool },
13461}
13462
13463impl LanguageServerLogType {
13464    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13465        match self {
13466            Self::Log(log_type) => {
13467                use proto::log_message::LogLevel;
13468                let level = match *log_type {
13469                    MessageType::ERROR => LogLevel::Error,
13470                    MessageType::WARNING => LogLevel::Warning,
13471                    MessageType::INFO => LogLevel::Info,
13472                    MessageType::LOG => LogLevel::Log,
13473                    other => {
13474                        log::warn!("Unknown lsp log message type: {other:?}");
13475                        LogLevel::Log
13476                    }
13477                };
13478                proto::language_server_log::LogType::Log(proto::LogMessage {
13479                    level: level as i32,
13480                })
13481            }
13482            Self::Trace { verbose_info } => {
13483                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13484                    verbose_info: verbose_info.to_owned(),
13485                })
13486            }
13487            Self::Rpc { received } => {
13488                let kind = if *received {
13489                    proto::rpc_message::Kind::Received
13490                } else {
13491                    proto::rpc_message::Kind::Sent
13492                };
13493                let kind = kind as i32;
13494                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13495            }
13496        }
13497    }
13498
13499    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13500        use proto::log_message::LogLevel;
13501        use proto::rpc_message;
13502        match log_type {
13503            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13504                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13505                    LogLevel::Error => MessageType::ERROR,
13506                    LogLevel::Warning => MessageType::WARNING,
13507                    LogLevel::Info => MessageType::INFO,
13508                    LogLevel::Log => MessageType::LOG,
13509                },
13510            ),
13511            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13512                verbose_info: trace_message.verbose_info,
13513            },
13514            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13515                received: match rpc_message::Kind::from_i32(message.kind)
13516                    .unwrap_or(rpc_message::Kind::Received)
13517                {
13518                    rpc_message::Kind::Received => true,
13519                    rpc_message::Kind::Sent => false,
13520                },
13521            },
13522        }
13523    }
13524}
13525
13526pub struct WorkspaceRefreshTask {
13527    refresh_tx: mpsc::Sender<()>,
13528    progress_tx: mpsc::Sender<()>,
13529    #[allow(dead_code)]
13530    task: Task<()>,
13531}
13532
13533pub enum LanguageServerState {
13534    Starting {
13535        startup: Task<Option<Arc<LanguageServer>>>,
13536        /// List of language servers that will be added to the workspace once it's initialization completes.
13537        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13538    },
13539
13540    Running {
13541        adapter: Arc<CachedLspAdapter>,
13542        server: Arc<LanguageServer>,
13543        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13544        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13545    },
13546}
13547
13548impl LanguageServerState {
13549    fn add_workspace_folder(&self, uri: Uri) {
13550        match self {
13551            LanguageServerState::Starting {
13552                pending_workspace_folders,
13553                ..
13554            } => {
13555                pending_workspace_folders.lock().insert(uri);
13556            }
13557            LanguageServerState::Running { server, .. } => {
13558                server.add_workspace_folder(uri);
13559            }
13560        }
13561    }
13562    fn _remove_workspace_folder(&self, uri: Uri) {
13563        match self {
13564            LanguageServerState::Starting {
13565                pending_workspace_folders,
13566                ..
13567            } => {
13568                pending_workspace_folders.lock().remove(&uri);
13569            }
13570            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13571        }
13572    }
13573}
13574
13575impl std::fmt::Debug for LanguageServerState {
13576    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13577        match self {
13578            LanguageServerState::Starting { .. } => {
13579                f.debug_struct("LanguageServerState::Starting").finish()
13580            }
13581            LanguageServerState::Running { .. } => {
13582                f.debug_struct("LanguageServerState::Running").finish()
13583            }
13584        }
13585    }
13586}
13587
13588#[derive(Clone, Debug, Serialize)]
13589pub struct LanguageServerProgress {
13590    pub is_disk_based_diagnostics_progress: bool,
13591    pub is_cancellable: bool,
13592    pub title: Option<String>,
13593    pub message: Option<String>,
13594    pub percentage: Option<usize>,
13595    #[serde(skip_serializing)]
13596    pub last_update_at: Instant,
13597}
13598
13599#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13600pub struct DiagnosticSummary {
13601    pub error_count: usize,
13602    pub warning_count: usize,
13603}
13604
13605impl DiagnosticSummary {
13606    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13607        let mut this = Self {
13608            error_count: 0,
13609            warning_count: 0,
13610        };
13611
13612        for entry in diagnostics {
13613            if entry.diagnostic.is_primary {
13614                match entry.diagnostic.severity {
13615                    DiagnosticSeverity::ERROR => this.error_count += 1,
13616                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13617                    _ => {}
13618                }
13619            }
13620        }
13621
13622        this
13623    }
13624
13625    pub fn is_empty(&self) -> bool {
13626        self.error_count == 0 && self.warning_count == 0
13627    }
13628
13629    pub fn to_proto(
13630        self,
13631        language_server_id: LanguageServerId,
13632        path: &RelPath,
13633    ) -> proto::DiagnosticSummary {
13634        proto::DiagnosticSummary {
13635            path: path.to_proto(),
13636            language_server_id: language_server_id.0 as u64,
13637            error_count: self.error_count as u32,
13638            warning_count: self.warning_count as u32,
13639        }
13640    }
13641}
13642
13643#[derive(Clone, Debug)]
13644pub enum CompletionDocumentation {
13645    /// There is no documentation for this completion.
13646    Undocumented,
13647    /// A single line of documentation.
13648    SingleLine(SharedString),
13649    /// Multiple lines of plain text documentation.
13650    MultiLinePlainText(SharedString),
13651    /// Markdown documentation.
13652    MultiLineMarkdown(SharedString),
13653    /// Both single line and multiple lines of plain text documentation.
13654    SingleLineAndMultiLinePlainText {
13655        single_line: SharedString,
13656        plain_text: Option<SharedString>,
13657    },
13658}
13659
13660impl CompletionDocumentation {
13661    #[cfg(any(test, feature = "test-support"))]
13662    pub fn text(&self) -> SharedString {
13663        match self {
13664            CompletionDocumentation::Undocumented => "".into(),
13665            CompletionDocumentation::SingleLine(s) => s.clone(),
13666            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13667            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13668            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13669                single_line.clone()
13670            }
13671        }
13672    }
13673}
13674
13675impl From<lsp::Documentation> for CompletionDocumentation {
13676    fn from(docs: lsp::Documentation) -> Self {
13677        match docs {
13678            lsp::Documentation::String(text) => {
13679                if text.lines().count() <= 1 {
13680                    CompletionDocumentation::SingleLine(text.into())
13681                } else {
13682                    CompletionDocumentation::MultiLinePlainText(text.into())
13683                }
13684            }
13685
13686            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13687                lsp::MarkupKind::PlainText => {
13688                    if value.lines().count() <= 1 {
13689                        CompletionDocumentation::SingleLine(value.into())
13690                    } else {
13691                        CompletionDocumentation::MultiLinePlainText(value.into())
13692                    }
13693                }
13694
13695                lsp::MarkupKind::Markdown => {
13696                    CompletionDocumentation::MultiLineMarkdown(value.into())
13697                }
13698            },
13699        }
13700    }
13701}
13702
13703pub enum ResolvedHint {
13704    Resolved(InlayHint),
13705    Resolving(Shared<Task<()>>),
13706}
13707
13708fn glob_literal_prefix(glob: &Path) -> PathBuf {
13709    glob.components()
13710        .take_while(|component| match component {
13711            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13712            _ => true,
13713        })
13714        .collect()
13715}
13716
13717pub struct SshLspAdapter {
13718    name: LanguageServerName,
13719    binary: LanguageServerBinary,
13720    initialization_options: Option<String>,
13721    code_action_kinds: Option<Vec<CodeActionKind>>,
13722}
13723
13724impl SshLspAdapter {
13725    pub fn new(
13726        name: LanguageServerName,
13727        binary: LanguageServerBinary,
13728        initialization_options: Option<String>,
13729        code_action_kinds: Option<String>,
13730    ) -> Self {
13731        Self {
13732            name,
13733            binary,
13734            initialization_options,
13735            code_action_kinds: code_action_kinds
13736                .as_ref()
13737                .and_then(|c| serde_json::from_str(c).ok()),
13738        }
13739    }
13740}
13741
13742impl LspInstaller for SshLspAdapter {
13743    type BinaryVersion = ();
13744    async fn check_if_user_installed(
13745        &self,
13746        _: &dyn LspAdapterDelegate,
13747        _: Option<Toolchain>,
13748        _: &AsyncApp,
13749    ) -> Option<LanguageServerBinary> {
13750        Some(self.binary.clone())
13751    }
13752
13753    async fn cached_server_binary(
13754        &self,
13755        _: PathBuf,
13756        _: &dyn LspAdapterDelegate,
13757    ) -> Option<LanguageServerBinary> {
13758        None
13759    }
13760
13761    async fn fetch_latest_server_version(
13762        &self,
13763        _: &dyn LspAdapterDelegate,
13764        _: bool,
13765        _: &mut AsyncApp,
13766    ) -> Result<()> {
13767        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13768    }
13769
13770    async fn fetch_server_binary(
13771        &self,
13772        _: (),
13773        _: PathBuf,
13774        _: &dyn LspAdapterDelegate,
13775    ) -> Result<LanguageServerBinary> {
13776        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13777    }
13778}
13779
13780#[async_trait(?Send)]
13781impl LspAdapter for SshLspAdapter {
13782    fn name(&self) -> LanguageServerName {
13783        self.name.clone()
13784    }
13785
13786    async fn initialization_options(
13787        self: Arc<Self>,
13788        _: &Arc<dyn LspAdapterDelegate>,
13789    ) -> Result<Option<serde_json::Value>> {
13790        let Some(options) = &self.initialization_options else {
13791            return Ok(None);
13792        };
13793        let result = serde_json::from_str(options)?;
13794        Ok(result)
13795    }
13796
13797    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13798        self.code_action_kinds.clone()
13799    }
13800}
13801
13802pub fn language_server_settings<'a>(
13803    delegate: &'a dyn LspAdapterDelegate,
13804    language: &LanguageServerName,
13805    cx: &'a App,
13806) -> Option<&'a LspSettings> {
13807    language_server_settings_for(
13808        SettingsLocation {
13809            worktree_id: delegate.worktree_id(),
13810            path: RelPath::empty(),
13811        },
13812        language,
13813        cx,
13814    )
13815}
13816
13817pub fn language_server_settings_for<'a>(
13818    location: SettingsLocation<'a>,
13819    language: &LanguageServerName,
13820    cx: &'a App,
13821) -> Option<&'a LspSettings> {
13822    ProjectSettings::get(Some(location), cx).lsp.get(language)
13823}
13824
13825pub struct LocalLspAdapterDelegate {
13826    lsp_store: WeakEntity<LspStore>,
13827    worktree: worktree::Snapshot,
13828    fs: Arc<dyn Fs>,
13829    http_client: Arc<dyn HttpClient>,
13830    language_registry: Arc<LanguageRegistry>,
13831    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13832}
13833
13834impl LocalLspAdapterDelegate {
13835    pub fn new(
13836        language_registry: Arc<LanguageRegistry>,
13837        environment: &Entity<ProjectEnvironment>,
13838        lsp_store: WeakEntity<LspStore>,
13839        worktree: &Entity<Worktree>,
13840        http_client: Arc<dyn HttpClient>,
13841        fs: Arc<dyn Fs>,
13842        cx: &mut App,
13843    ) -> Arc<Self> {
13844        let load_shell_env_task =
13845            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13846
13847        Arc::new(Self {
13848            lsp_store,
13849            worktree: worktree.read(cx).snapshot(),
13850            fs,
13851            http_client,
13852            language_registry,
13853            load_shell_env_task,
13854        })
13855    }
13856
13857    fn from_local_lsp(
13858        local: &LocalLspStore,
13859        worktree: &Entity<Worktree>,
13860        cx: &mut App,
13861    ) -> Arc<Self> {
13862        Self::new(
13863            local.languages.clone(),
13864            &local.environment,
13865            local.weak.clone(),
13866            worktree,
13867            local.http_client.clone(),
13868            local.fs.clone(),
13869            cx,
13870        )
13871    }
13872}
13873
13874#[async_trait]
13875impl LspAdapterDelegate for LocalLspAdapterDelegate {
13876    fn show_notification(&self, message: &str, cx: &mut App) {
13877        self.lsp_store
13878            .update(cx, |_, cx| {
13879                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13880            })
13881            .ok();
13882    }
13883
13884    fn http_client(&self) -> Arc<dyn HttpClient> {
13885        self.http_client.clone()
13886    }
13887
13888    fn worktree_id(&self) -> WorktreeId {
13889        self.worktree.id()
13890    }
13891
13892    fn worktree_root_path(&self) -> &Path {
13893        self.worktree.abs_path().as_ref()
13894    }
13895
13896    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13897        self.worktree.resolve_executable_path(path)
13898    }
13899
13900    async fn shell_env(&self) -> HashMap<String, String> {
13901        let task = self.load_shell_env_task.clone();
13902        task.await.unwrap_or_default()
13903    }
13904
13905    async fn npm_package_installed_version(
13906        &self,
13907        package_name: &str,
13908    ) -> Result<Option<(PathBuf, String)>> {
13909        let local_package_directory = self.worktree_root_path();
13910        let node_modules_directory = local_package_directory.join("node_modules");
13911
13912        if let Some(version) =
13913            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13914        {
13915            return Ok(Some((node_modules_directory, version)));
13916        }
13917        let Some(npm) = self.which("npm".as_ref()).await else {
13918            log::warn!(
13919                "Failed to find npm executable for {:?}",
13920                local_package_directory
13921            );
13922            return Ok(None);
13923        };
13924
13925        let env = self.shell_env().await;
13926        let output = util::command::new_smol_command(&npm)
13927            .args(["root", "-g"])
13928            .envs(env)
13929            .current_dir(local_package_directory)
13930            .output()
13931            .await?;
13932        let global_node_modules =
13933            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13934
13935        if let Some(version) =
13936            read_package_installed_version(global_node_modules.clone(), package_name).await?
13937        {
13938            return Ok(Some((global_node_modules, version)));
13939        }
13940        return Ok(None);
13941    }
13942
13943    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13944        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13945        if self.fs.is_file(&worktree_abs_path).await {
13946            worktree_abs_path.pop();
13947        }
13948
13949        let env = self.shell_env().await;
13950
13951        let shell_path = env.get("PATH").cloned();
13952
13953        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13954    }
13955
13956    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13957        let mut working_dir = self.worktree_root_path().to_path_buf();
13958        if self.fs.is_file(&working_dir).await {
13959            working_dir.pop();
13960        }
13961        let output = util::command::new_smol_command(&command.path)
13962            .args(command.arguments)
13963            .envs(command.env.clone().unwrap_or_default())
13964            .current_dir(working_dir)
13965            .output()
13966            .await?;
13967
13968        anyhow::ensure!(
13969            output.status.success(),
13970            "{}, stdout: {:?}, stderr: {:?}",
13971            output.status,
13972            String::from_utf8_lossy(&output.stdout),
13973            String::from_utf8_lossy(&output.stderr)
13974        );
13975        Ok(())
13976    }
13977
13978    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13979        self.language_registry
13980            .update_lsp_binary_status(server_name, status);
13981    }
13982
13983    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13984        self.language_registry
13985            .all_lsp_adapters()
13986            .into_iter()
13987            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13988            .collect()
13989    }
13990
13991    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13992        let dir = self.language_registry.language_server_download_dir(name)?;
13993
13994        if !dir.exists() {
13995            smol::fs::create_dir_all(&dir)
13996                .await
13997                .context("failed to create container directory")
13998                .log_err()?;
13999        }
14000
14001        Some(dir)
14002    }
14003
14004    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14005        let entry = self
14006            .worktree
14007            .entry_for_path(path)
14008            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14009        let abs_path = self.worktree.absolutize(&entry.path);
14010        self.fs.load(&abs_path).await
14011    }
14012}
14013
14014async fn populate_labels_for_symbols(
14015    symbols: Vec<CoreSymbol>,
14016    language_registry: &Arc<LanguageRegistry>,
14017    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14018    output: &mut Vec<Symbol>,
14019) {
14020    #[allow(clippy::mutable_key_type)]
14021    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14022
14023    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14024    for symbol in symbols {
14025        let Some(file_name) = symbol.path.file_name() else {
14026            continue;
14027        };
14028        let language = language_registry
14029            .load_language_for_file_path(Path::new(file_name))
14030            .await
14031            .ok()
14032            .or_else(|| {
14033                unknown_paths.insert(file_name.into());
14034                None
14035            });
14036        symbols_by_language
14037            .entry(language)
14038            .or_default()
14039            .push(symbol);
14040    }
14041
14042    for unknown_path in unknown_paths {
14043        log::info!("no language found for symbol in file {unknown_path:?}");
14044    }
14045
14046    let mut label_params = Vec::new();
14047    for (language, mut symbols) in symbols_by_language {
14048        label_params.clear();
14049        label_params.extend(
14050            symbols
14051                .iter_mut()
14052                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14053        );
14054
14055        let mut labels = Vec::new();
14056        if let Some(language) = language {
14057            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14058                language_registry
14059                    .lsp_adapters(&language.name())
14060                    .first()
14061                    .cloned()
14062            });
14063            if let Some(lsp_adapter) = lsp_adapter {
14064                labels = lsp_adapter
14065                    .labels_for_symbols(&label_params, &language)
14066                    .await
14067                    .log_err()
14068                    .unwrap_or_default();
14069            }
14070        }
14071
14072        for ((symbol, (name, _)), label) in symbols
14073            .into_iter()
14074            .zip(label_params.drain(..))
14075            .zip(labels.into_iter().chain(iter::repeat(None)))
14076        {
14077            output.push(Symbol {
14078                language_server_name: symbol.language_server_name,
14079                source_worktree_id: symbol.source_worktree_id,
14080                source_language_server_id: symbol.source_language_server_id,
14081                path: symbol.path,
14082                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14083                name,
14084                kind: symbol.kind,
14085                range: symbol.range,
14086            });
14087        }
14088    }
14089}
14090
14091fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14092    match server.capabilities().text_document_sync.as_ref()? {
14093        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14094            // Server wants didSave but didn't specify includeText.
14095            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14096            // Server doesn't want didSave at all.
14097            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14098            // Server provided SaveOptions.
14099            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14100                Some(save_options.include_text.unwrap_or(false))
14101            }
14102        },
14103        // We do not have any save info. Kind affects didChange only.
14104        lsp::TextDocumentSyncCapability::Kind(_) => None,
14105    }
14106}
14107
14108/// Completion items are displayed in a `UniformList`.
14109/// Usually, those items are single-line strings, but in LSP responses,
14110/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14111/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14112/// 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,
14113/// breaking the completions menu presentation.
14114///
14115/// 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.
14116fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14117    let mut new_text = String::with_capacity(label.text.len());
14118    let mut offset_map = vec![0; label.text.len() + 1];
14119    let mut last_char_was_space = false;
14120    let mut new_idx = 0;
14121    let chars = label.text.char_indices().fuse();
14122    let mut newlines_removed = false;
14123
14124    for (idx, c) in chars {
14125        offset_map[idx] = new_idx;
14126
14127        match c {
14128            '\n' if last_char_was_space => {
14129                newlines_removed = true;
14130            }
14131            '\t' | ' ' if last_char_was_space => {}
14132            '\n' if !last_char_was_space => {
14133                new_text.push(' ');
14134                new_idx += 1;
14135                last_char_was_space = true;
14136                newlines_removed = true;
14137            }
14138            ' ' | '\t' => {
14139                new_text.push(' ');
14140                new_idx += 1;
14141                last_char_was_space = true;
14142            }
14143            _ => {
14144                new_text.push(c);
14145                new_idx += c.len_utf8();
14146                last_char_was_space = false;
14147            }
14148        }
14149    }
14150    offset_map[label.text.len()] = new_idx;
14151
14152    // Only modify the label if newlines were removed.
14153    if !newlines_removed {
14154        return;
14155    }
14156
14157    let last_index = new_idx;
14158    let mut run_ranges_errors = Vec::new();
14159    label.runs.retain_mut(|(range, _)| {
14160        match offset_map.get(range.start) {
14161            Some(&start) => range.start = start,
14162            None => {
14163                run_ranges_errors.push(range.clone());
14164                return false;
14165            }
14166        }
14167
14168        match offset_map.get(range.end) {
14169            Some(&end) => range.end = end,
14170            None => {
14171                run_ranges_errors.push(range.clone());
14172                range.end = last_index;
14173            }
14174        }
14175        true
14176    });
14177    if !run_ranges_errors.is_empty() {
14178        log::error!(
14179            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14180            label.text
14181        );
14182    }
14183
14184    let mut wrong_filter_range = None;
14185    if label.filter_range == (0..label.text.len()) {
14186        label.filter_range = 0..new_text.len();
14187    } else {
14188        let mut original_filter_range = Some(label.filter_range.clone());
14189        match offset_map.get(label.filter_range.start) {
14190            Some(&start) => label.filter_range.start = start,
14191            None => {
14192                wrong_filter_range = original_filter_range.take();
14193                label.filter_range.start = last_index;
14194            }
14195        }
14196
14197        match offset_map.get(label.filter_range.end) {
14198            Some(&end) => label.filter_range.end = end,
14199            None => {
14200                wrong_filter_range = original_filter_range.take();
14201                label.filter_range.end = last_index;
14202            }
14203        }
14204    }
14205    if let Some(wrong_filter_range) = wrong_filter_range {
14206        log::error!(
14207            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14208            label.text
14209        );
14210    }
14211
14212    label.text = new_text;
14213}
14214
14215#[cfg(test)]
14216mod tests {
14217    use language::HighlightId;
14218
14219    use super::*;
14220
14221    #[test]
14222    fn test_glob_literal_prefix() {
14223        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
14224        assert_eq!(
14225            glob_literal_prefix(Path::new("node_modules/**/*.js")),
14226            Path::new("node_modules")
14227        );
14228        assert_eq!(
14229            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14230            Path::new("foo")
14231        );
14232        assert_eq!(
14233            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14234            Path::new("foo/bar/baz.js")
14235        );
14236
14237        #[cfg(target_os = "windows")]
14238        {
14239            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14240            assert_eq!(
14241                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14242                Path::new("node_modules")
14243            );
14244            assert_eq!(
14245                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14246                Path::new("foo")
14247            );
14248            assert_eq!(
14249                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14250                Path::new("foo/bar/baz.js")
14251            );
14252        }
14253    }
14254
14255    #[test]
14256    fn test_multi_len_chars_normalization() {
14257        let mut label = CodeLabel::new(
14258            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14259            0..6,
14260            vec![(0..6, HighlightId(1))],
14261        );
14262        ensure_uniform_list_compatible_label(&mut label);
14263        assert_eq!(
14264            label,
14265            CodeLabel::new(
14266                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14267                0..6,
14268                vec![(0..6, HighlightId(1))],
14269            )
14270        );
14271    }
14272}