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 lsp_ext_command;
   15pub mod rust_analyzer_ext;
   16
   17use crate::{
   18    CodeAction, ColorPresentation, Completion, CompletionResponse, CompletionSource,
   19    CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction, LspPullDiagnostics,
   20    ManifestProvidersStore, ProjectItem, ProjectPath, ProjectTransaction, PulledDiagnostics,
   21    ResolveState, Symbol,
   22    buffer_store::{BufferStore, BufferStoreEvent},
   23    environment::ProjectEnvironment,
   24    lsp_command::{self, *},
   25    lsp_store,
   26    manifest_tree::{
   27        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   28        ManifestTree,
   29    },
   30    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   31    project_settings::{LspSettings, ProjectSettings},
   32    relativize_path, resolve_path,
   33    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   34    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   35    yarn::YarnPathStore,
   36};
   37use anyhow::{Context as _, Result, anyhow};
   38use async_trait::async_trait;
   39use client::{TypedEnvelope, proto};
   40use clock::Global;
   41use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   42use futures::{
   43    AsyncWriteExt, Future, FutureExt, StreamExt,
   44    future::{Either, Shared, join_all, pending, select},
   45    select, select_biased,
   46    stream::FuturesUnordered,
   47};
   48use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   49use gpui::{
   50    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   51    WeakEntity,
   52};
   53use http_client::HttpClient;
   54use itertools::Itertools as _;
   55use language::{
   56    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   57    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   58    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, ManifestDelegate, ManifestName,
   59    Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain, Transaction,
   60    Unclipped,
   61    language_settings::{
   62        FormatOnSave, Formatter, LanguageSettings, SelectedFormatter, language_settings,
   63    },
   64    point_to_lsp,
   65    proto::{
   66        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   67        serialize_lsp_edit, serialize_version,
   68    },
   69    range_from_lsp, range_to_lsp,
   70};
   71use lsp::{
   72    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticSeverity,
   73    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
   74    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
   75    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   76    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   77    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, WillRenameFiles,
   78    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   79};
   80use node_runtime::read_package_installed_version;
   81use parking_lot::Mutex;
   82use postage::{mpsc, sink::Sink, stream::Stream, watch};
   83use rand::prelude::*;
   84
   85use rpc::{
   86    AnyProtoClient,
   87    proto::{FromProto, ToProto},
   88};
   89use serde::Serialize;
   90use settings::{Settings, SettingsLocation, SettingsStore};
   91use sha2::{Digest, Sha256};
   92use smol::channel::Sender;
   93use snippet::Snippet;
   94use std::{
   95    any::Any,
   96    borrow::Cow,
   97    cell::RefCell,
   98    cmp::{Ordering, Reverse},
   99    convert::TryInto,
  100    ffi::OsStr,
  101    future::ready,
  102    iter, mem,
  103    ops::{ControlFlow, Range},
  104    path::{self, Path, PathBuf},
  105    pin::pin,
  106    rc::Rc,
  107    sync::Arc,
  108    time::{Duration, Instant},
  109};
  110use sum_tree::Dimensions;
  111use text::{Anchor, BufferId, LineEnding, OffsetRangeExt};
  112use url::Url;
  113use util::{
  114    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  115    paths::{PathExt, SanitizedPath},
  116    post_inc,
  117};
  118
  119pub use fs::*;
  120pub use language::Location;
  121#[cfg(any(test, feature = "test-support"))]
  122pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  123pub use worktree::{
  124    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  125    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  126};
  127
  128const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  129pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  130
  131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  132pub enum FormatTrigger {
  133    Save,
  134    Manual,
  135}
  136
  137pub enum LspFormatTarget {
  138    Buffers,
  139    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  140}
  141
  142pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  143
  144impl FormatTrigger {
  145    fn from_proto(value: i32) -> FormatTrigger {
  146        match value {
  147            0 => FormatTrigger::Save,
  148            1 => FormatTrigger::Manual,
  149            _ => FormatTrigger::Save,
  150        }
  151    }
  152}
  153
  154#[derive(Clone)]
  155struct UnifiedLanguageServer {
  156    id: LanguageServerId,
  157    project_roots: HashSet<Arc<Path>>,
  158}
  159
  160#[derive(Clone, Hash, PartialEq, Eq)]
  161struct LanguageServerSeed {
  162    worktree_id: WorktreeId,
  163    name: LanguageServerName,
  164    toolchain: Option<Toolchain>,
  165    settings: Arc<LspSettings>,
  166}
  167
  168#[derive(Debug)]
  169pub struct DocumentDiagnosticsUpdate<'a, D> {
  170    pub diagnostics: D,
  171    pub result_id: Option<String>,
  172    pub server_id: LanguageServerId,
  173    pub disk_based_sources: Cow<'a, [String]>,
  174}
  175
  176pub struct DocumentDiagnostics {
  177    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  178    document_abs_path: PathBuf,
  179    version: Option<i32>,
  180}
  181
  182pub struct LocalLspStore {
  183    weak: WeakEntity<LspStore>,
  184    worktree_store: Entity<WorktreeStore>,
  185    toolchain_store: Entity<LocalToolchainStore>,
  186    http_client: Arc<dyn HttpClient>,
  187    environment: Entity<ProjectEnvironment>,
  188    fs: Arc<dyn Fs>,
  189    languages: Arc<LanguageRegistry>,
  190    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  191    yarn: Entity<YarnPathStore>,
  192    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  193    buffers_being_formatted: HashSet<BufferId>,
  194    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  195    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  196    watched_manifest_filenames: HashSet<ManifestName>,
  197    language_server_paths_watched_for_rename:
  198        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  199    language_server_watcher_registrations:
  200        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
  201    supplementary_language_servers:
  202        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  203    prettier_store: Entity<PrettierStore>,
  204    next_diagnostic_group_id: usize,
  205    diagnostics: HashMap<
  206        WorktreeId,
  207        HashMap<
  208            Arc<Path>,
  209            Vec<(
  210                LanguageServerId,
  211                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  212            )>,
  213        >,
  214    >,
  215    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  216    _subscription: gpui::Subscription,
  217    lsp_tree: LanguageServerTree,
  218    registered_buffers: HashMap<BufferId, usize>,
  219    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  220    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  221}
  222
  223impl LocalLspStore {
  224    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  225    pub fn running_language_server_for_id(
  226        &self,
  227        id: LanguageServerId,
  228    ) -> Option<&Arc<LanguageServer>> {
  229        let language_server_state = self.language_servers.get(&id)?;
  230
  231        match language_server_state {
  232            LanguageServerState::Running { server, .. } => Some(server),
  233            LanguageServerState::Starting { .. } => None,
  234        }
  235    }
  236
  237    fn get_or_insert_language_server(
  238        &mut self,
  239        worktree_handle: &Entity<Worktree>,
  240        delegate: Arc<LocalLspAdapterDelegate>,
  241        disposition: &Arc<LaunchDisposition>,
  242        language_name: &LanguageName,
  243        cx: &mut App,
  244    ) -> LanguageServerId {
  245        let key = LanguageServerSeed {
  246            worktree_id: worktree_handle.read(cx).id(),
  247            name: disposition.server_name.clone(),
  248            settings: disposition.settings.clone(),
  249            toolchain: disposition.toolchain.clone(),
  250        };
  251        if let Some(state) = self.language_server_ids.get_mut(&key) {
  252            state.project_roots.insert(disposition.path.path.clone());
  253            state.id
  254        } else {
  255            let adapter = self
  256                .languages
  257                .lsp_adapters(language_name)
  258                .into_iter()
  259                .find(|adapter| adapter.name() == disposition.server_name)
  260                .expect("To find LSP adapter");
  261            let new_language_server_id = self.start_language_server(
  262                worktree_handle,
  263                delegate,
  264                adapter,
  265                disposition.settings.clone(),
  266                key.clone(),
  267                cx,
  268            );
  269            if let Some(state) = self.language_server_ids.get_mut(&key) {
  270                state.project_roots.insert(disposition.path.path.clone());
  271            } else {
  272                debug_assert!(
  273                    false,
  274                    "Expected `start_language_server` to ensure that `key` exists in a map"
  275                );
  276            }
  277            new_language_server_id
  278        }
  279    }
  280
  281    fn start_language_server(
  282        &mut self,
  283        worktree_handle: &Entity<Worktree>,
  284        delegate: Arc<LocalLspAdapterDelegate>,
  285        adapter: Arc<CachedLspAdapter>,
  286        settings: Arc<LspSettings>,
  287        key: LanguageServerSeed,
  288        cx: &mut App,
  289    ) -> LanguageServerId {
  290        let worktree = worktree_handle.read(cx);
  291
  292        let root_path = worktree.abs_path();
  293        let toolchain = key.toolchain.clone();
  294        let override_options = settings.initialization_options.clone();
  295
  296        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  297
  298        let server_id = self.languages.next_language_server_id();
  299        log::trace!(
  300            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  301            adapter.name.0
  302        );
  303
  304        let binary = self.get_language_server_binary(
  305            adapter.clone(),
  306            settings,
  307            toolchain.clone(),
  308            delegate.clone(),
  309            true,
  310            cx,
  311        );
  312        let pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
  313
  314        let pending_server = cx.spawn({
  315            let adapter = adapter.clone();
  316            let server_name = adapter.name.clone();
  317            let stderr_capture = stderr_capture.clone();
  318            #[cfg(any(test, feature = "test-support"))]
  319            let lsp_store = self.weak.clone();
  320            let pending_workspace_folders = pending_workspace_folders.clone();
  321            async move |cx| {
  322                let binary = binary.await?;
  323                #[cfg(any(test, feature = "test-support"))]
  324                if let Some(server) = lsp_store
  325                    .update(&mut cx.clone(), |this, cx| {
  326                        this.languages.create_fake_language_server(
  327                            server_id,
  328                            &server_name,
  329                            binary.clone(),
  330                            &mut cx.to_async(),
  331                        )
  332                    })
  333                    .ok()
  334                    .flatten()
  335                {
  336                    return Ok(server);
  337                }
  338
  339                let code_action_kinds = adapter.code_action_kinds();
  340                lsp::LanguageServer::new(
  341                    stderr_capture,
  342                    server_id,
  343                    server_name,
  344                    binary,
  345                    &root_path,
  346                    code_action_kinds,
  347                    Some(pending_workspace_folders),
  348                    cx,
  349                )
  350            }
  351        });
  352
  353        let startup = {
  354            let server_name = adapter.name.0.clone();
  355            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  356            let key = key.clone();
  357            let adapter = adapter.clone();
  358            let lsp_store = self.weak.clone();
  359            let pending_workspace_folders = pending_workspace_folders.clone();
  360            let fs = self.fs.clone();
  361            let pull_diagnostics = ProjectSettings::get_global(cx)
  362                .diagnostics
  363                .lsp_pull_diagnostics
  364                .enabled;
  365            cx.spawn(async move |cx| {
  366                let result = async {
  367                    let language_server = pending_server.await?;
  368
  369                    let workspace_config = Self::workspace_configuration_for_adapter(
  370                        adapter.adapter.clone(),
  371                        fs.as_ref(),
  372                        &delegate,
  373                        toolchain,
  374                        cx,
  375                    )
  376                    .await?;
  377
  378                    let mut initialization_options = Self::initialization_options_for_adapter(
  379                        adapter.adapter.clone(),
  380                        fs.as_ref(),
  381                        &delegate,
  382                    )
  383                    .await?;
  384
  385                    match (&mut initialization_options, override_options) {
  386                        (Some(initialization_options), Some(override_options)) => {
  387                            merge_json_value_into(override_options, initialization_options);
  388                        }
  389                        (None, override_options) => initialization_options = override_options,
  390                        _ => {}
  391                    }
  392
  393                    let initialization_params = cx.update(|cx| {
  394                        let mut params =
  395                            language_server.default_initialize_params(pull_diagnostics, cx);
  396                        params.initialization_options = initialization_options;
  397                        adapter.adapter.prepare_initialize_params(params, cx)
  398                    })??;
  399
  400                    Self::setup_lsp_messages(
  401                        lsp_store.clone(),
  402                        fs,
  403                        &language_server,
  404                        delegate.clone(),
  405                        adapter.clone(),
  406                    );
  407
  408                    let did_change_configuration_params =
  409                        Arc::new(lsp::DidChangeConfigurationParams {
  410                            settings: workspace_config,
  411                        });
  412                    let language_server = cx
  413                        .update(|cx| {
  414                            language_server.initialize(
  415                                initialization_params,
  416                                did_change_configuration_params.clone(),
  417                                cx,
  418                            )
  419                        })?
  420                        .await
  421                        .inspect_err(|_| {
  422                            if let Some(lsp_store) = lsp_store.upgrade() {
  423                                lsp_store
  424                                    .update(cx, |lsp_store, cx| {
  425                                        lsp_store.cleanup_lsp_data(server_id);
  426                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  427                                    })
  428                                    .ok();
  429                            }
  430                        })?;
  431
  432                    language_server
  433                        .notify::<lsp::notification::DidChangeConfiguration>(
  434                            &did_change_configuration_params,
  435                        )
  436                        .ok();
  437
  438                    anyhow::Ok(language_server)
  439                }
  440                .await;
  441
  442                match result {
  443                    Ok(server) => {
  444                        lsp_store
  445                            .update(cx, |lsp_store, cx| {
  446                                lsp_store.insert_newly_running_language_server(
  447                                    adapter,
  448                                    server.clone(),
  449                                    server_id,
  450                                    key,
  451                                    pending_workspace_folders,
  452                                    cx,
  453                                );
  454                            })
  455                            .ok();
  456                        stderr_capture.lock().take();
  457                        Some(server)
  458                    }
  459
  460                    Err(err) => {
  461                        let log = stderr_capture.lock().take().unwrap_or_default();
  462                        delegate.update_status(
  463                            adapter.name(),
  464                            BinaryStatus::Failed {
  465                                error: if log.is_empty() {
  466                                    format!("{err:#}")
  467                                } else {
  468                                    format!("{err:#}\n-- stderr --\n{log}")
  469                                },
  470                            },
  471                        );
  472                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  473                        if !log.is_empty() {
  474                            log::error!("server stderr: {log}");
  475                        }
  476                        None
  477                    }
  478                }
  479            })
  480        };
  481        let state = LanguageServerState::Starting {
  482            startup,
  483            pending_workspace_folders,
  484        };
  485
  486        self.languages
  487            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  488
  489        self.language_servers.insert(server_id, state);
  490        self.language_server_ids
  491            .entry(key)
  492            .or_insert(UnifiedLanguageServer {
  493                id: server_id,
  494                project_roots: Default::default(),
  495            });
  496        server_id
  497    }
  498
  499    fn get_language_server_binary(
  500        &self,
  501        adapter: Arc<CachedLspAdapter>,
  502        settings: Arc<LspSettings>,
  503        toolchain: Option<Toolchain>,
  504        delegate: Arc<dyn LspAdapterDelegate>,
  505        allow_binary_download: bool,
  506        cx: &mut App,
  507    ) -> Task<Result<LanguageServerBinary>> {
  508        if let Some(settings) = settings.binary.as_ref()
  509            && settings.path.is_some()
  510        {
  511            let settings = settings.clone();
  512
  513            return cx.background_spawn(async move {
  514                let mut env = delegate.shell_env().await;
  515                env.extend(settings.env.unwrap_or_default());
  516
  517                Ok(LanguageServerBinary {
  518                    path: PathBuf::from(&settings.path.unwrap()),
  519                    env: Some(env),
  520                    arguments: settings
  521                        .arguments
  522                        .unwrap_or_default()
  523                        .iter()
  524                        .map(Into::into)
  525                        .collect(),
  526                })
  527            });
  528        }
  529        let lsp_binary_options = LanguageServerBinaryOptions {
  530            allow_path_lookup: !settings
  531                .binary
  532                .as_ref()
  533                .and_then(|b| b.ignore_system_version)
  534                .unwrap_or_default(),
  535            allow_binary_download,
  536        };
  537
  538        cx.spawn(async move |cx| {
  539            let binary_result = adapter
  540                .clone()
  541                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  542                .await;
  543
  544            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  545
  546            let mut binary = binary_result?;
  547            let mut shell_env = delegate.shell_env().await;
  548
  549            shell_env.extend(binary.env.unwrap_or_default());
  550
  551            if let Some(settings) = settings.binary.as_ref() {
  552                if let Some(arguments) = &settings.arguments {
  553                    binary.arguments = arguments.iter().map(Into::into).collect();
  554                }
  555                if let Some(env) = &settings.env {
  556                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  557                }
  558            }
  559
  560            binary.env = Some(shell_env);
  561            Ok(binary)
  562        })
  563    }
  564
  565    fn setup_lsp_messages(
  566        this: WeakEntity<LspStore>,
  567        fs: Arc<dyn Fs>,
  568        language_server: &LanguageServer,
  569        delegate: Arc<dyn LspAdapterDelegate>,
  570        adapter: Arc<CachedLspAdapter>,
  571    ) {
  572        let name = language_server.name();
  573        let server_id = language_server.server_id();
  574        language_server
  575            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  576                let adapter = adapter.clone();
  577                let this = this.clone();
  578                move |mut params, cx| {
  579                    let adapter = adapter.clone();
  580                    if let Some(this) = this.upgrade() {
  581                        this.update(cx, |this, cx| {
  582                            {
  583                                let buffer = params
  584                                    .uri
  585                                    .to_file_path()
  586                                    .map(|file_path| this.get_buffer(&file_path, cx))
  587                                    .ok()
  588                                    .flatten();
  589                                adapter.process_diagnostics(&mut params, server_id, buffer);
  590                            }
  591
  592                            this.merge_lsp_diagnostics(
  593                                DiagnosticSourceKind::Pushed,
  594                                vec![DocumentDiagnosticsUpdate {
  595                                    server_id,
  596                                    diagnostics: params,
  597                                    result_id: None,
  598                                    disk_based_sources: Cow::Borrowed(
  599                                        &adapter.disk_based_diagnostic_sources,
  600                                    ),
  601                                }],
  602                                |_, diagnostic, cx| match diagnostic.source_kind {
  603                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  604                                        adapter.retain_old_diagnostic(diagnostic, cx)
  605                                    }
  606                                    DiagnosticSourceKind::Pulled => true,
  607                                },
  608                                cx,
  609                            )
  610                            .log_err();
  611                        })
  612                        .ok();
  613                    }
  614                }
  615            })
  616            .detach();
  617        language_server
  618            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  619                let adapter = adapter.adapter.clone();
  620                let delegate = delegate.clone();
  621                let this = this.clone();
  622                let fs = fs.clone();
  623                move |params, cx| {
  624                    let adapter = adapter.clone();
  625                    let delegate = delegate.clone();
  626                    let this = this.clone();
  627                    let fs = fs.clone();
  628                    let mut cx = cx.clone();
  629                    async move {
  630                        let toolchain_for_id = this
  631                            .update(&mut cx, |this, _| {
  632                                this.as_local()?.language_server_ids.iter().find_map(
  633                                    |(seed, value)| {
  634                                        (value.id == server_id).then(|| seed.toolchain.clone())
  635                                    },
  636                                )
  637                            })?
  638                            .context("Expected the LSP store to be in a local mode")?;
  639                        let workspace_config = Self::workspace_configuration_for_adapter(
  640                            adapter.clone(),
  641                            fs.as_ref(),
  642                            &delegate,
  643                            toolchain_for_id,
  644                            &mut cx,
  645                        )
  646                        .await?;
  647
  648                        Ok(params
  649                            .items
  650                            .into_iter()
  651                            .map(|item| {
  652                                if let Some(section) = &item.section {
  653                                    workspace_config
  654                                        .get(section)
  655                                        .cloned()
  656                                        .unwrap_or(serde_json::Value::Null)
  657                                } else {
  658                                    workspace_config.clone()
  659                                }
  660                            })
  661                            .collect())
  662                    }
  663                }
  664            })
  665            .detach();
  666
  667        language_server
  668            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  669                let this = this.clone();
  670                move |_, cx| {
  671                    let this = this.clone();
  672                    let cx = cx.clone();
  673                    async move {
  674                        let Some(server) =
  675                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  676                        else {
  677                            return Ok(None);
  678                        };
  679                        let root = server.workspace_folders();
  680                        Ok(Some(
  681                            root.into_iter()
  682                                .map(|uri| WorkspaceFolder {
  683                                    uri,
  684                                    name: Default::default(),
  685                                })
  686                                .collect(),
  687                        ))
  688                    }
  689                }
  690            })
  691            .detach();
  692        // Even though we don't have handling for these requests, respond to them to
  693        // avoid stalling any language server like `gopls` which waits for a response
  694        // to these requests when initializing.
  695        language_server
  696            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  697                let this = this.clone();
  698                move |params, cx| {
  699                    let this = this.clone();
  700                    let mut cx = cx.clone();
  701                    async move {
  702                        this.update(&mut cx, |this, _| {
  703                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  704                                && let lsp::NumberOrString::String(token) = params.token
  705                            {
  706                                status.progress_tokens.insert(token);
  707                            }
  708                        })?;
  709
  710                        Ok(())
  711                    }
  712                }
  713            })
  714            .detach();
  715
  716        language_server
  717            .on_request::<lsp::request::RegisterCapability, _, _>({
  718                let lsp_store = this.clone();
  719                move |params, cx| {
  720                    let lsp_store = lsp_store.clone();
  721                    let mut cx = cx.clone();
  722                    async move {
  723                        lsp_store
  724                            .update(&mut cx, |lsp_store, cx| {
  725                                if lsp_store.as_local().is_some() {
  726                                    match lsp_store
  727                                        .register_server_capabilities(server_id, params, cx)
  728                                    {
  729                                        Ok(()) => {}
  730                                        Err(e) => {
  731                                            log::error!(
  732                                                "Failed to register server capabilities: {e:#}"
  733                                            );
  734                                        }
  735                                    };
  736                                }
  737                            })
  738                            .ok();
  739                        Ok(())
  740                    }
  741                }
  742            })
  743            .detach();
  744
  745        language_server
  746            .on_request::<lsp::request::UnregisterCapability, _, _>({
  747                let lsp_store = this.clone();
  748                move |params, cx| {
  749                    let lsp_store = lsp_store.clone();
  750                    let mut cx = cx.clone();
  751                    async move {
  752                        lsp_store
  753                            .update(&mut cx, |lsp_store, cx| {
  754                                if lsp_store.as_local().is_some() {
  755                                    match lsp_store
  756                                        .unregister_server_capabilities(server_id, params, cx)
  757                                    {
  758                                        Ok(()) => {}
  759                                        Err(e) => {
  760                                            log::error!(
  761                                                "Failed to unregister server capabilities: {e:#}"
  762                                            );
  763                                        }
  764                                    }
  765                                }
  766                            })
  767                            .ok();
  768                        Ok(())
  769                    }
  770                }
  771            })
  772            .detach();
  773
  774        language_server
  775            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  776                let this = this.clone();
  777                move |params, cx| {
  778                    let mut cx = cx.clone();
  779                    let this = this.clone();
  780                    async move {
  781                        LocalLspStore::on_lsp_workspace_edit(
  782                            this.clone(),
  783                            params,
  784                            server_id,
  785                            &mut cx,
  786                        )
  787                        .await
  788                    }
  789                }
  790            })
  791            .detach();
  792
  793        language_server
  794            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  795                let this = this.clone();
  796                move |(), cx| {
  797                    let this = this.clone();
  798                    let mut cx = cx.clone();
  799                    async move {
  800                        this.update(&mut cx, |this, cx| {
  801                            cx.emit(LspStoreEvent::RefreshInlayHints);
  802                            this.downstream_client.as_ref().map(|(client, project_id)| {
  803                                client.send(proto::RefreshInlayHints {
  804                                    project_id: *project_id,
  805                                })
  806                            })
  807                        })?
  808                        .transpose()?;
  809                        Ok(())
  810                    }
  811                }
  812            })
  813            .detach();
  814
  815        language_server
  816            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  817                let this = this.clone();
  818                move |(), cx| {
  819                    let this = this.clone();
  820                    let mut cx = cx.clone();
  821                    async move {
  822                        this.update(&mut cx, |this, cx| {
  823                            cx.emit(LspStoreEvent::RefreshCodeLens);
  824                            this.downstream_client.as_ref().map(|(client, project_id)| {
  825                                client.send(proto::RefreshCodeLens {
  826                                    project_id: *project_id,
  827                                })
  828                            })
  829                        })?
  830                        .transpose()?;
  831                        Ok(())
  832                    }
  833                }
  834            })
  835            .detach();
  836
  837        language_server
  838            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  839                let this = this.clone();
  840                move |(), cx| {
  841                    let this = this.clone();
  842                    let mut cx = cx.clone();
  843                    async move {
  844                        this.update(&mut cx, |lsp_store, _| {
  845                            lsp_store.pull_workspace_diagnostics(server_id);
  846                            lsp_store
  847                                .downstream_client
  848                                .as_ref()
  849                                .map(|(client, project_id)| {
  850                                    client.send(proto::PullWorkspaceDiagnostics {
  851                                        project_id: *project_id,
  852                                        server_id: server_id.to_proto(),
  853                                    })
  854                                })
  855                        })?
  856                        .transpose()?;
  857                        Ok(())
  858                    }
  859                }
  860            })
  861            .detach();
  862
  863        language_server
  864            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  865                let this = this.clone();
  866                let name = name.to_string();
  867                move |params, cx| {
  868                    let this = this.clone();
  869                    let name = name.to_string();
  870                    let mut cx = cx.clone();
  871                    async move {
  872                        let actions = params.actions.unwrap_or_default();
  873                        let (tx, rx) = smol::channel::bounded(1);
  874                        let request = LanguageServerPromptRequest {
  875                            level: match params.typ {
  876                                lsp::MessageType::ERROR => PromptLevel::Critical,
  877                                lsp::MessageType::WARNING => PromptLevel::Warning,
  878                                _ => PromptLevel::Info,
  879                            },
  880                            message: params.message,
  881                            actions,
  882                            response_channel: tx,
  883                            lsp_name: name.clone(),
  884                        };
  885
  886                        let did_update = this
  887                            .update(&mut cx, |_, cx| {
  888                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  889                            })
  890                            .is_ok();
  891                        if did_update {
  892                            let response = rx.recv().await.ok();
  893                            Ok(response)
  894                        } else {
  895                            Ok(None)
  896                        }
  897                    }
  898                }
  899            })
  900            .detach();
  901        language_server
  902            .on_notification::<lsp::notification::ShowMessage, _>({
  903                let this = this.clone();
  904                let name = name.to_string();
  905                move |params, cx| {
  906                    let this = this.clone();
  907                    let name = name.to_string();
  908                    let mut cx = cx.clone();
  909
  910                    let (tx, _) = smol::channel::bounded(1);
  911                    let request = LanguageServerPromptRequest {
  912                        level: match params.typ {
  913                            lsp::MessageType::ERROR => PromptLevel::Critical,
  914                            lsp::MessageType::WARNING => PromptLevel::Warning,
  915                            _ => PromptLevel::Info,
  916                        },
  917                        message: params.message,
  918                        actions: vec![],
  919                        response_channel: tx,
  920                        lsp_name: name,
  921                    };
  922
  923                    let _ = this.update(&mut cx, |_, cx| {
  924                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  925                    });
  926                }
  927            })
  928            .detach();
  929
  930        let disk_based_diagnostics_progress_token =
  931            adapter.disk_based_diagnostics_progress_token.clone();
  932
  933        language_server
  934            .on_notification::<lsp::notification::Progress, _>({
  935                let this = this.clone();
  936                move |params, cx| {
  937                    if let Some(this) = this.upgrade() {
  938                        this.update(cx, |this, cx| {
  939                            this.on_lsp_progress(
  940                                params,
  941                                server_id,
  942                                disk_based_diagnostics_progress_token.clone(),
  943                                cx,
  944                            );
  945                        })
  946                        .ok();
  947                    }
  948                }
  949            })
  950            .detach();
  951
  952        language_server
  953            .on_notification::<lsp::notification::LogMessage, _>({
  954                let this = this.clone();
  955                move |params, cx| {
  956                    if let Some(this) = this.upgrade() {
  957                        this.update(cx, |_, cx| {
  958                            cx.emit(LspStoreEvent::LanguageServerLog(
  959                                server_id,
  960                                LanguageServerLogType::Log(params.typ),
  961                                params.message,
  962                            ));
  963                        })
  964                        .ok();
  965                    }
  966                }
  967            })
  968            .detach();
  969
  970        language_server
  971            .on_notification::<lsp::notification::LogTrace, _>({
  972                let this = this.clone();
  973                move |params, cx| {
  974                    let mut cx = cx.clone();
  975                    if let Some(this) = this.upgrade() {
  976                        this.update(&mut cx, |_, cx| {
  977                            cx.emit(LspStoreEvent::LanguageServerLog(
  978                                server_id,
  979                                LanguageServerLogType::Trace(params.verbose),
  980                                params.message,
  981                            ));
  982                        })
  983                        .ok();
  984                    }
  985                }
  986            })
  987            .detach();
  988
  989        json_language_server_ext::register_requests(this.clone(), language_server);
  990        rust_analyzer_ext::register_notifications(this.clone(), language_server);
  991        clangd_ext::register_notifications(this, language_server, adapter);
  992    }
  993
  994    fn shutdown_language_servers_on_quit(
  995        &mut self,
  996        _: &mut Context<LspStore>,
  997    ) -> impl Future<Output = ()> + use<> {
  998        let shutdown_futures = self
  999            .language_servers
 1000            .drain()
 1001            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1002            .collect::<Vec<_>>();
 1003
 1004        async move {
 1005            join_all(shutdown_futures).await;
 1006        }
 1007    }
 1008
 1009    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1010        match server_state {
 1011            LanguageServerState::Running { server, .. } => {
 1012                if let Some(shutdown) = server.shutdown() {
 1013                    shutdown.await;
 1014                }
 1015            }
 1016            LanguageServerState::Starting { startup, .. } => {
 1017                if let Some(server) = startup.await
 1018                    && let Some(shutdown) = server.shutdown()
 1019                {
 1020                    shutdown.await;
 1021                }
 1022            }
 1023        }
 1024        Ok(())
 1025    }
 1026
 1027    fn language_servers_for_worktree(
 1028        &self,
 1029        worktree_id: WorktreeId,
 1030    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1031        self.language_server_ids
 1032            .iter()
 1033            .filter_map(move |(seed, state)| {
 1034                if seed.worktree_id != worktree_id {
 1035                    return None;
 1036                }
 1037
 1038                if let Some(LanguageServerState::Running { server, .. }) =
 1039                    self.language_servers.get(&state.id)
 1040                {
 1041                    Some(server)
 1042                } else {
 1043                    None
 1044                }
 1045            })
 1046    }
 1047
 1048    fn language_server_ids_for_project_path(
 1049        &self,
 1050        project_path: ProjectPath,
 1051        language: &Language,
 1052        cx: &mut App,
 1053    ) -> Vec<LanguageServerId> {
 1054        let Some(worktree) = self
 1055            .worktree_store
 1056            .read(cx)
 1057            .worktree_for_id(project_path.worktree_id, cx)
 1058        else {
 1059            return Vec::new();
 1060        };
 1061        let delegate: Arc<dyn ManifestDelegate> =
 1062            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1063
 1064        self.lsp_tree
 1065            .get(
 1066                project_path,
 1067                language.name(),
 1068                language.manifest(),
 1069                &delegate,
 1070                cx,
 1071            )
 1072            .collect::<Vec<_>>()
 1073    }
 1074
 1075    fn language_server_ids_for_buffer(
 1076        &self,
 1077        buffer: &Buffer,
 1078        cx: &mut App,
 1079    ) -> Vec<LanguageServerId> {
 1080        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1081            let worktree_id = file.worktree_id(cx);
 1082
 1083            let path: Arc<Path> = file
 1084                .path()
 1085                .parent()
 1086                .map(Arc::from)
 1087                .unwrap_or_else(|| file.path().clone());
 1088            let worktree_path = ProjectPath { worktree_id, path };
 1089            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1090        } else {
 1091            Vec::new()
 1092        }
 1093    }
 1094
 1095    fn language_servers_for_buffer<'a>(
 1096        &'a self,
 1097        buffer: &'a Buffer,
 1098        cx: &'a mut App,
 1099    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1100        self.language_server_ids_for_buffer(buffer, cx)
 1101            .into_iter()
 1102            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1103                LanguageServerState::Running {
 1104                    adapter, server, ..
 1105                } => Some((adapter, server)),
 1106                _ => None,
 1107            })
 1108    }
 1109
 1110    async fn execute_code_action_kind_locally(
 1111        lsp_store: WeakEntity<LspStore>,
 1112        mut buffers: Vec<Entity<Buffer>>,
 1113        kind: CodeActionKind,
 1114        push_to_history: bool,
 1115        cx: &mut AsyncApp,
 1116    ) -> anyhow::Result<ProjectTransaction> {
 1117        // Do not allow multiple concurrent code actions requests for the
 1118        // same buffer.
 1119        lsp_store.update(cx, |this, cx| {
 1120            let this = this.as_local_mut().unwrap();
 1121            buffers.retain(|buffer| {
 1122                this.buffers_being_formatted
 1123                    .insert(buffer.read(cx).remote_id())
 1124            });
 1125        })?;
 1126        let _cleanup = defer({
 1127            let this = lsp_store.clone();
 1128            let mut cx = cx.clone();
 1129            let buffers = &buffers;
 1130            move || {
 1131                this.update(&mut cx, |this, cx| {
 1132                    let this = this.as_local_mut().unwrap();
 1133                    for buffer in buffers {
 1134                        this.buffers_being_formatted
 1135                            .remove(&buffer.read(cx).remote_id());
 1136                    }
 1137                })
 1138                .ok();
 1139            }
 1140        });
 1141        let mut project_transaction = ProjectTransaction::default();
 1142
 1143        for buffer in &buffers {
 1144            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1145                buffer.update(cx, |buffer, cx| {
 1146                    lsp_store
 1147                        .as_local()
 1148                        .unwrap()
 1149                        .language_servers_for_buffer(buffer, cx)
 1150                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1151                        .collect::<Vec<_>>()
 1152                })
 1153            })?;
 1154            for (_, language_server) in adapters_and_servers.iter() {
 1155                let actions = Self::get_server_code_actions_from_action_kinds(
 1156                    &lsp_store,
 1157                    language_server.server_id(),
 1158                    vec![kind.clone()],
 1159                    buffer,
 1160                    cx,
 1161                )
 1162                .await?;
 1163                Self::execute_code_actions_on_server(
 1164                    &lsp_store,
 1165                    language_server,
 1166                    actions,
 1167                    push_to_history,
 1168                    &mut project_transaction,
 1169                    cx,
 1170                )
 1171                .await?;
 1172            }
 1173        }
 1174        Ok(project_transaction)
 1175    }
 1176
 1177    async fn format_locally(
 1178        lsp_store: WeakEntity<LspStore>,
 1179        mut buffers: Vec<FormattableBuffer>,
 1180        push_to_history: bool,
 1181        trigger: FormatTrigger,
 1182        logger: zlog::Logger,
 1183        cx: &mut AsyncApp,
 1184    ) -> anyhow::Result<ProjectTransaction> {
 1185        // Do not allow multiple concurrent formatting requests for the
 1186        // same buffer.
 1187        lsp_store.update(cx, |this, cx| {
 1188            let this = this.as_local_mut().unwrap();
 1189            buffers.retain(|buffer| {
 1190                this.buffers_being_formatted
 1191                    .insert(buffer.handle.read(cx).remote_id())
 1192            });
 1193        })?;
 1194
 1195        let _cleanup = defer({
 1196            let this = lsp_store.clone();
 1197            let mut cx = cx.clone();
 1198            let buffers = &buffers;
 1199            move || {
 1200                this.update(&mut cx, |this, cx| {
 1201                    let this = this.as_local_mut().unwrap();
 1202                    for buffer in buffers {
 1203                        this.buffers_being_formatted
 1204                            .remove(&buffer.handle.read(cx).remote_id());
 1205                    }
 1206                })
 1207                .ok();
 1208            }
 1209        });
 1210
 1211        let mut project_transaction = ProjectTransaction::default();
 1212
 1213        for buffer in &buffers {
 1214            zlog::debug!(
 1215                logger =>
 1216                "formatting buffer '{:?}'",
 1217                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1218            );
 1219            // Create an empty transaction to hold all of the formatting edits.
 1220            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1221                // ensure no transactions created while formatting are
 1222                // grouped with the previous transaction in the history
 1223                // based on the transaction group interval
 1224                buffer.finalize_last_transaction();
 1225                buffer
 1226                    .start_transaction()
 1227                    .context("transaction already open")?;
 1228                buffer.end_transaction(cx);
 1229                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1230                buffer.finalize_last_transaction();
 1231                anyhow::Ok(transaction_id)
 1232            })??;
 1233
 1234            let result = Self::format_buffer_locally(
 1235                lsp_store.clone(),
 1236                buffer,
 1237                formatting_transaction_id,
 1238                trigger,
 1239                logger,
 1240                cx,
 1241            )
 1242            .await;
 1243
 1244            buffer.handle.update(cx, |buffer, cx| {
 1245                let Some(formatting_transaction) =
 1246                    buffer.get_transaction(formatting_transaction_id).cloned()
 1247                else {
 1248                    zlog::warn!(logger => "no formatting transaction");
 1249                    return;
 1250                };
 1251                if formatting_transaction.edit_ids.is_empty() {
 1252                    zlog::debug!(logger => "no changes made while formatting");
 1253                    buffer.forget_transaction(formatting_transaction_id);
 1254                    return;
 1255                }
 1256                if !push_to_history {
 1257                    zlog::trace!(logger => "forgetting format transaction");
 1258                    buffer.forget_transaction(formatting_transaction.id);
 1259                }
 1260                project_transaction
 1261                    .0
 1262                    .insert(cx.entity(), formatting_transaction);
 1263            })?;
 1264
 1265            result?;
 1266        }
 1267
 1268        Ok(project_transaction)
 1269    }
 1270
 1271    async fn format_buffer_locally(
 1272        lsp_store: WeakEntity<LspStore>,
 1273        buffer: &FormattableBuffer,
 1274        formatting_transaction_id: clock::Lamport,
 1275        trigger: FormatTrigger,
 1276        logger: zlog::Logger,
 1277        cx: &mut AsyncApp,
 1278    ) -> Result<()> {
 1279        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1280            buffer.handle.update(cx, |buffer, cx| {
 1281                let adapters_and_servers = lsp_store
 1282                    .as_local()
 1283                    .unwrap()
 1284                    .language_servers_for_buffer(buffer, cx)
 1285                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1286                    .collect::<Vec<_>>();
 1287                let settings =
 1288                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1289                        .into_owned();
 1290                (adapters_and_servers, settings)
 1291            })
 1292        })?;
 1293
 1294        /// Apply edits to the buffer that will become part of the formatting transaction.
 1295        /// Fails if the buffer has been edited since the start of that transaction.
 1296        fn extend_formatting_transaction(
 1297            buffer: &FormattableBuffer,
 1298            formatting_transaction_id: text::TransactionId,
 1299            cx: &mut AsyncApp,
 1300            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1301        ) -> anyhow::Result<()> {
 1302            buffer.handle.update(cx, |buffer, cx| {
 1303                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1304                if last_transaction_id != Some(formatting_transaction_id) {
 1305                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1306                }
 1307                buffer.start_transaction();
 1308                operation(buffer, cx);
 1309                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1310                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1311                }
 1312                Ok(())
 1313            })?
 1314        }
 1315
 1316        // handle whitespace formatting
 1317        if settings.remove_trailing_whitespace_on_save {
 1318            zlog::trace!(logger => "removing trailing whitespace");
 1319            let diff = buffer
 1320                .handle
 1321                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1322                .await;
 1323            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1324                buffer.apply_diff(diff, cx);
 1325            })?;
 1326        }
 1327
 1328        if settings.ensure_final_newline_on_save {
 1329            zlog::trace!(logger => "ensuring final newline");
 1330            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1331                buffer.ensure_final_newline(cx);
 1332            })?;
 1333        }
 1334
 1335        // Formatter for `code_actions_on_format` that runs before
 1336        // the rest of the formatters
 1337        let mut code_actions_on_format_formatter = None;
 1338        let should_run_code_actions_on_format = !matches!(
 1339            (trigger, &settings.format_on_save),
 1340            (FormatTrigger::Save, &FormatOnSave::Off)
 1341        );
 1342        if should_run_code_actions_on_format {
 1343            let have_code_actions_to_run_on_format = settings
 1344                .code_actions_on_format
 1345                .values()
 1346                .any(|enabled| *enabled);
 1347            if have_code_actions_to_run_on_format {
 1348                zlog::trace!(logger => "going to run code actions on format");
 1349                code_actions_on_format_formatter = Some(Formatter::CodeActions(
 1350                    settings.code_actions_on_format.clone(),
 1351                ));
 1352            }
 1353        }
 1354
 1355        let formatters = match (trigger, &settings.format_on_save) {
 1356            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1357            (FormatTrigger::Save, FormatOnSave::List(formatters)) => formatters.as_ref(),
 1358            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1359                match &settings.formatter {
 1360                    SelectedFormatter::Auto => {
 1361                        if settings.prettier.allowed {
 1362                            zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1363                            std::slice::from_ref(&Formatter::Prettier)
 1364                        } else {
 1365                            zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1366                            std::slice::from_ref(&Formatter::LanguageServer { name: None })
 1367                        }
 1368                    }
 1369                    SelectedFormatter::List(formatter_list) => formatter_list.as_ref(),
 1370                }
 1371            }
 1372        };
 1373
 1374        let formatters = code_actions_on_format_formatter.iter().chain(formatters);
 1375
 1376        for formatter in formatters {
 1377            match formatter {
 1378                Formatter::Prettier => {
 1379                    let logger = zlog::scoped!(logger => "prettier");
 1380                    zlog::trace!(logger => "formatting");
 1381                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1382
 1383                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1384                        lsp_store.prettier_store().unwrap().downgrade()
 1385                    })?;
 1386                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1387                        .await
 1388                        .transpose()?;
 1389                    let Some(diff) = diff else {
 1390                        zlog::trace!(logger => "No changes");
 1391                        continue;
 1392                    };
 1393
 1394                    extend_formatting_transaction(
 1395                        buffer,
 1396                        formatting_transaction_id,
 1397                        cx,
 1398                        |buffer, cx| {
 1399                            buffer.apply_diff(diff, cx);
 1400                        },
 1401                    )?;
 1402                }
 1403                Formatter::External { command, arguments } => {
 1404                    let logger = zlog::scoped!(logger => "command");
 1405                    zlog::trace!(logger => "formatting");
 1406                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1407
 1408                    let diff = Self::format_via_external_command(
 1409                        buffer,
 1410                        command.as_ref(),
 1411                        arguments.as_deref(),
 1412                        cx,
 1413                    )
 1414                    .await
 1415                    .with_context(|| {
 1416                        format!("Failed to format buffer via external command: {}", command)
 1417                    })?;
 1418                    let Some(diff) = diff else {
 1419                        zlog::trace!(logger => "No changes");
 1420                        continue;
 1421                    };
 1422
 1423                    extend_formatting_transaction(
 1424                        buffer,
 1425                        formatting_transaction_id,
 1426                        cx,
 1427                        |buffer, cx| {
 1428                            buffer.apply_diff(diff, cx);
 1429                        },
 1430                    )?;
 1431                }
 1432                Formatter::LanguageServer { name } => {
 1433                    let logger = zlog::scoped!(logger => "language-server");
 1434                    zlog::trace!(logger => "formatting");
 1435                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1436
 1437                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1438                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1439                        continue;
 1440                    };
 1441
 1442                    let language_server = if let Some(name) = name.as_deref() {
 1443                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1444                            if adapter.name.0.as_ref() == name {
 1445                                Some(server.clone())
 1446                            } else {
 1447                                None
 1448                            }
 1449                        })
 1450                    } else {
 1451                        adapters_and_servers.first().map(|e| e.1.clone())
 1452                    };
 1453
 1454                    let Some(language_server) = language_server else {
 1455                        log::debug!(
 1456                            "No language server found to format buffer '{:?}'. Skipping",
 1457                            buffer_path_abs.as_path().to_string_lossy()
 1458                        );
 1459                        continue;
 1460                    };
 1461
 1462                    zlog::trace!(
 1463                        logger =>
 1464                        "Formatting buffer '{:?}' using language server '{:?}'",
 1465                        buffer_path_abs.as_path().to_string_lossy(),
 1466                        language_server.name()
 1467                    );
 1468
 1469                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1470                        zlog::trace!(logger => "formatting ranges");
 1471                        Self::format_ranges_via_lsp(
 1472                            &lsp_store,
 1473                            &buffer.handle,
 1474                            ranges,
 1475                            buffer_path_abs,
 1476                            &language_server,
 1477                            &settings,
 1478                            cx,
 1479                        )
 1480                        .await
 1481                        .context("Failed to format ranges via language server")?
 1482                    } else {
 1483                        zlog::trace!(logger => "formatting full");
 1484                        Self::format_via_lsp(
 1485                            &lsp_store,
 1486                            &buffer.handle,
 1487                            buffer_path_abs,
 1488                            &language_server,
 1489                            &settings,
 1490                            cx,
 1491                        )
 1492                        .await
 1493                        .context("failed to format via language server")?
 1494                    };
 1495
 1496                    if edits.is_empty() {
 1497                        zlog::trace!(logger => "No changes");
 1498                        continue;
 1499                    }
 1500                    extend_formatting_transaction(
 1501                        buffer,
 1502                        formatting_transaction_id,
 1503                        cx,
 1504                        |buffer, cx| {
 1505                            buffer.edit(edits, None, cx);
 1506                        },
 1507                    )?;
 1508                }
 1509                Formatter::CodeActions(code_actions) => {
 1510                    let logger = zlog::scoped!(logger => "code-actions");
 1511                    zlog::trace!(logger => "formatting");
 1512                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1513
 1514                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1515                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1516                        continue;
 1517                    };
 1518                    let code_action_kinds = code_actions
 1519                        .iter()
 1520                        .filter_map(|(action_kind, enabled)| {
 1521                            enabled.then_some(action_kind.clone().into())
 1522                        })
 1523                        .collect::<Vec<_>>();
 1524                    if code_action_kinds.is_empty() {
 1525                        zlog::trace!(logger => "No code action kinds enabled, skipping");
 1526                        continue;
 1527                    }
 1528                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kinds);
 1529
 1530                    let mut actions_and_servers = Vec::new();
 1531
 1532                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1533                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1534                            &lsp_store,
 1535                            language_server.server_id(),
 1536                            code_action_kinds.clone(),
 1537                            &buffer.handle,
 1538                            cx,
 1539                        )
 1540                        .await
 1541                        .with_context(
 1542                            || format!("Failed to resolve code actions with kinds {:?} for language server {}",
 1543                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1544                                language_server.name())
 1545                        );
 1546                        let Ok(actions) = actions_result else {
 1547                            // note: it may be better to set result to the error and break formatters here
 1548                            // but for now we try to execute the actions that we can resolve and skip the rest
 1549                            zlog::error!(
 1550                                logger =>
 1551                                "Failed to resolve code actions with kinds {:?} with language server {}",
 1552                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1553                                language_server.name()
 1554                            );
 1555                            continue;
 1556                        };
 1557                        for action in actions {
 1558                            actions_and_servers.push((action, index));
 1559                        }
 1560                    }
 1561
 1562                    if actions_and_servers.is_empty() {
 1563                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1564                        continue;
 1565                    }
 1566
 1567                    'actions: for (mut action, server_index) in actions_and_servers {
 1568                        let server = &adapters_and_servers[server_index].1;
 1569
 1570                        let describe_code_action = |action: &CodeAction| {
 1571                            format!(
 1572                                "code action '{}' with title \"{}\" on server {}",
 1573                                action
 1574                                    .lsp_action
 1575                                    .action_kind()
 1576                                    .unwrap_or("unknown".into())
 1577                                    .as_str(),
 1578                                action.lsp_action.title(),
 1579                                server.name(),
 1580                            )
 1581                        };
 1582
 1583                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1584
 1585                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1586                            zlog::error!(
 1587                                logger =>
 1588                                "Failed to resolve {}. Error: {}",
 1589                                describe_code_action(&action),
 1590                                err
 1591                            );
 1592                            continue;
 1593                        }
 1594
 1595                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1596                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1597                            // but filters out and logs warnings for code actions that cause unreasonably
 1598                            // difficult handling on our part, such as:
 1599                            // - applying edits that call commands
 1600                            //   which can result in arbitrary workspace edits being sent from the server that
 1601                            //   have no way of being tied back to the command that initiated them (i.e. we
 1602                            //   can't know which edits are part of the format request, or if the server is done sending
 1603                            //   actions in response to the command)
 1604                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1605                            //   as we then would need to handle such changes correctly in the local history as well
 1606                            //   as the remote history through the ProjectTransaction
 1607                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1608                            // Supporting these actions is not impossible, but not supported as of yet.
 1609                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1610                                zlog::trace!(
 1611                                    logger =>
 1612                                    "No changes for code action. Skipping {}",
 1613                                    describe_code_action(&action),
 1614                                );
 1615                                continue;
 1616                            }
 1617
 1618                            let mut operations = Vec::new();
 1619                            if let Some(document_changes) = edit.document_changes {
 1620                                match document_changes {
 1621                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1622                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1623                                    ),
 1624                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1625                                }
 1626                            } else if let Some(changes) = edit.changes {
 1627                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1628                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1629                                        text_document:
 1630                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1631                                                uri,
 1632                                                version: None,
 1633                                            },
 1634                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1635                                    })
 1636                                }));
 1637                            }
 1638
 1639                            let mut edits = Vec::with_capacity(operations.len());
 1640
 1641                            if operations.is_empty() {
 1642                                zlog::trace!(
 1643                                    logger =>
 1644                                    "No changes for code action. Skipping {}",
 1645                                    describe_code_action(&action),
 1646                                );
 1647                                continue;
 1648                            }
 1649                            for operation in operations {
 1650                                let op = match operation {
 1651                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1652                                    lsp::DocumentChangeOperation::Op(_) => {
 1653                                        zlog::warn!(
 1654                                            logger =>
 1655                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1656                                            describe_code_action(&action),
 1657                                        );
 1658                                        continue 'actions;
 1659                                    }
 1660                                };
 1661                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1662                                    zlog::warn!(
 1663                                        logger =>
 1664                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1665                                        &op.text_document.uri,
 1666                                        describe_code_action(&action),
 1667                                    );
 1668                                    continue 'actions;
 1669                                };
 1670                                if &file_path != buffer_path_abs {
 1671                                    zlog::warn!(
 1672                                        logger =>
 1673                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1674                                        file_path,
 1675                                        buffer_path_abs,
 1676                                        describe_code_action(&action),
 1677                                    );
 1678                                    continue 'actions;
 1679                                }
 1680
 1681                                let mut lsp_edits = Vec::new();
 1682                                for edit in op.edits {
 1683                                    match edit {
 1684                                        Edit::Plain(edit) => {
 1685                                            if !lsp_edits.contains(&edit) {
 1686                                                lsp_edits.push(edit);
 1687                                            }
 1688                                        }
 1689                                        Edit::Annotated(edit) => {
 1690                                            if !lsp_edits.contains(&edit.text_edit) {
 1691                                                lsp_edits.push(edit.text_edit);
 1692                                            }
 1693                                        }
 1694                                        Edit::Snippet(_) => {
 1695                                            zlog::warn!(
 1696                                                logger =>
 1697                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1698                                                describe_code_action(&action),
 1699                                            );
 1700                                            continue 'actions;
 1701                                        }
 1702                                    }
 1703                                }
 1704                                let edits_result = lsp_store
 1705                                    .update(cx, |lsp_store, cx| {
 1706                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1707                                            &buffer.handle,
 1708                                            lsp_edits,
 1709                                            server.server_id(),
 1710                                            op.text_document.version,
 1711                                            cx,
 1712                                        )
 1713                                    })?
 1714                                    .await;
 1715                                let Ok(resolved_edits) = edits_result else {
 1716                                    zlog::warn!(
 1717                                        logger =>
 1718                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1719                                        buffer_path_abs.as_path(),
 1720                                        describe_code_action(&action),
 1721                                    );
 1722                                    continue 'actions;
 1723                                };
 1724                                edits.extend(resolved_edits);
 1725                            }
 1726
 1727                            if edits.is_empty() {
 1728                                zlog::warn!(logger => "No edits resolved from LSP");
 1729                                continue;
 1730                            }
 1731
 1732                            extend_formatting_transaction(
 1733                                buffer,
 1734                                formatting_transaction_id,
 1735                                cx,
 1736                                |buffer, cx| {
 1737                                    buffer.edit(edits, None, cx);
 1738                                },
 1739                            )?;
 1740                        }
 1741
 1742                        if let Some(command) = action.lsp_action.command() {
 1743                            zlog::warn!(
 1744                                logger =>
 1745                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1746                                &command.command,
 1747                            );
 1748
 1749                            // bail early if command is invalid
 1750                            let server_capabilities = server.capabilities();
 1751                            let available_commands = server_capabilities
 1752                                .execute_command_provider
 1753                                .as_ref()
 1754                                .map(|options| options.commands.as_slice())
 1755                                .unwrap_or_default();
 1756                            if !available_commands.contains(&command.command) {
 1757                                zlog::warn!(
 1758                                    logger =>
 1759                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1760                                    command.command,
 1761                                    server.name(),
 1762                                );
 1763                                continue;
 1764                            }
 1765
 1766                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1767                            extend_formatting_transaction(
 1768                                buffer,
 1769                                formatting_transaction_id,
 1770                                cx,
 1771                                |_, _| {},
 1772                            )?;
 1773                            zlog::info!(logger => "Executing command {}", &command.command);
 1774
 1775                            lsp_store.update(cx, |this, _| {
 1776                                this.as_local_mut()
 1777                                    .unwrap()
 1778                                    .last_workspace_edits_by_language_server
 1779                                    .remove(&server.server_id());
 1780                            })?;
 1781
 1782                            let execute_command_result = server
 1783                                .request::<lsp::request::ExecuteCommand>(
 1784                                    lsp::ExecuteCommandParams {
 1785                                        command: command.command.clone(),
 1786                                        arguments: command.arguments.clone().unwrap_or_default(),
 1787                                        ..Default::default()
 1788                                    },
 1789                                )
 1790                                .await
 1791                                .into_response();
 1792
 1793                            if execute_command_result.is_err() {
 1794                                zlog::error!(
 1795                                    logger =>
 1796                                    "Failed to execute command '{}' as part of {}",
 1797                                    &command.command,
 1798                                    describe_code_action(&action),
 1799                                );
 1800                                continue 'actions;
 1801                            }
 1802
 1803                            let mut project_transaction_command =
 1804                                lsp_store.update(cx, |this, _| {
 1805                                    this.as_local_mut()
 1806                                        .unwrap()
 1807                                        .last_workspace_edits_by_language_server
 1808                                        .remove(&server.server_id())
 1809                                        .unwrap_or_default()
 1810                                })?;
 1811
 1812                            if let Some(transaction) =
 1813                                project_transaction_command.0.remove(&buffer.handle)
 1814                            {
 1815                                zlog::trace!(
 1816                                    logger =>
 1817                                    "Successfully captured {} edits that resulted from command {}",
 1818                                    transaction.edit_ids.len(),
 1819                                    &command.command,
 1820                                );
 1821                                let transaction_id_project_transaction = transaction.id;
 1822                                buffer.handle.update(cx, |buffer, _| {
 1823                                    // it may have been removed from history if push_to_history was
 1824                                    // false in deserialize_workspace_edit. If so push it so we
 1825                                    // can merge it with the format transaction
 1826                                    // and pop the combined transaction off the history stack
 1827                                    // later if push_to_history is false
 1828                                    if buffer.get_transaction(transaction.id).is_none() {
 1829                                        buffer.push_transaction(transaction, Instant::now());
 1830                                    }
 1831                                    buffer.merge_transactions(
 1832                                        transaction_id_project_transaction,
 1833                                        formatting_transaction_id,
 1834                                    );
 1835                                })?;
 1836                            }
 1837
 1838                            if !project_transaction_command.0.is_empty() {
 1839                                let extra_buffers = project_transaction_command
 1840                                    .0
 1841                                    .keys()
 1842                                    .filter_map(|buffer_handle| {
 1843                                        buffer_handle
 1844                                            .read_with(cx, |b, cx| b.project_path(cx))
 1845                                            .ok()
 1846                                            .flatten()
 1847                                    })
 1848                                    .map(|p| p.path.to_sanitized_string())
 1849                                    .join(", ");
 1850                                zlog::warn!(
 1851                                    logger =>
 1852                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1853                                    &command.command,
 1854                                    extra_buffers,
 1855                                );
 1856                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1857                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1858                                // add it so it's included, and merge it into the format transaction when its created later
 1859                            }
 1860                        }
 1861                    }
 1862                }
 1863            }
 1864        }
 1865
 1866        Ok(())
 1867    }
 1868
 1869    pub async fn format_ranges_via_lsp(
 1870        this: &WeakEntity<LspStore>,
 1871        buffer_handle: &Entity<Buffer>,
 1872        ranges: &[Range<Anchor>],
 1873        abs_path: &Path,
 1874        language_server: &Arc<LanguageServer>,
 1875        settings: &LanguageSettings,
 1876        cx: &mut AsyncApp,
 1877    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1878        let capabilities = &language_server.capabilities();
 1879        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1880        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1881            anyhow::bail!(
 1882                "{} language server does not support range formatting",
 1883                language_server.name()
 1884            );
 1885        }
 1886
 1887        let uri = file_path_to_lsp_url(abs_path)?;
 1888        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1889
 1890        let lsp_edits = {
 1891            let mut lsp_ranges = Vec::new();
 1892            this.update(cx, |_this, cx| {
 1893                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1894                // not have been sent to the language server. This seems like a fairly systemic
 1895                // issue, though, the resolution probably is not specific to formatting.
 1896                //
 1897                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1898                // LSP.
 1899                let snapshot = buffer_handle.read(cx).snapshot();
 1900                for range in ranges {
 1901                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1902                }
 1903                anyhow::Ok(())
 1904            })??;
 1905
 1906            let mut edits = None;
 1907            for range in lsp_ranges {
 1908                if let Some(mut edit) = language_server
 1909                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1910                        text_document: text_document.clone(),
 1911                        range,
 1912                        options: lsp_command::lsp_formatting_options(settings),
 1913                        work_done_progress_params: Default::default(),
 1914                    })
 1915                    .await
 1916                    .into_response()?
 1917                {
 1918                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1919                }
 1920            }
 1921            edits
 1922        };
 1923
 1924        if let Some(lsp_edits) = lsp_edits {
 1925            this.update(cx, |this, cx| {
 1926                this.as_local_mut().unwrap().edits_from_lsp(
 1927                    buffer_handle,
 1928                    lsp_edits,
 1929                    language_server.server_id(),
 1930                    None,
 1931                    cx,
 1932                )
 1933            })?
 1934            .await
 1935        } else {
 1936            Ok(Vec::with_capacity(0))
 1937        }
 1938    }
 1939
 1940    async fn format_via_lsp(
 1941        this: &WeakEntity<LspStore>,
 1942        buffer: &Entity<Buffer>,
 1943        abs_path: &Path,
 1944        language_server: &Arc<LanguageServer>,
 1945        settings: &LanguageSettings,
 1946        cx: &mut AsyncApp,
 1947    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1948        let logger = zlog::scoped!("lsp_format");
 1949        zlog::info!(logger => "Formatting via LSP");
 1950
 1951        let uri = file_path_to_lsp_url(abs_path)?;
 1952        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1953        let capabilities = &language_server.capabilities();
 1954
 1955        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1956        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1957
 1958        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1959            let _timer = zlog::time!(logger => "format-full");
 1960            language_server
 1961                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1962                    text_document,
 1963                    options: lsp_command::lsp_formatting_options(settings),
 1964                    work_done_progress_params: Default::default(),
 1965                })
 1966                .await
 1967                .into_response()?
 1968        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1969            let _timer = zlog::time!(logger => "format-range");
 1970            let buffer_start = lsp::Position::new(0, 0);
 1971            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 1972            language_server
 1973                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1974                    text_document: text_document.clone(),
 1975                    range: lsp::Range::new(buffer_start, buffer_end),
 1976                    options: lsp_command::lsp_formatting_options(settings),
 1977                    work_done_progress_params: Default::default(),
 1978                })
 1979                .await
 1980                .into_response()?
 1981        } else {
 1982            None
 1983        };
 1984
 1985        if let Some(lsp_edits) = lsp_edits {
 1986            this.update(cx, |this, cx| {
 1987                this.as_local_mut().unwrap().edits_from_lsp(
 1988                    buffer,
 1989                    lsp_edits,
 1990                    language_server.server_id(),
 1991                    None,
 1992                    cx,
 1993                )
 1994            })?
 1995            .await
 1996        } else {
 1997            Ok(Vec::with_capacity(0))
 1998        }
 1999    }
 2000
 2001    async fn format_via_external_command(
 2002        buffer: &FormattableBuffer,
 2003        command: &str,
 2004        arguments: Option<&[String]>,
 2005        cx: &mut AsyncApp,
 2006    ) -> Result<Option<Diff>> {
 2007        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2008            let file = File::from_dyn(buffer.file())?;
 2009            let worktree = file.worktree.read(cx);
 2010            let mut worktree_path = worktree.abs_path().to_path_buf();
 2011            if worktree.root_entry()?.is_file() {
 2012                worktree_path.pop();
 2013            }
 2014            Some(worktree_path)
 2015        })?;
 2016
 2017        let mut child = util::command::new_smol_command(command);
 2018
 2019        if let Some(buffer_env) = buffer.env.as_ref() {
 2020            child.envs(buffer_env);
 2021        }
 2022
 2023        if let Some(working_dir_path) = working_dir_path {
 2024            child.current_dir(working_dir_path);
 2025        }
 2026
 2027        if let Some(arguments) = arguments {
 2028            child.args(arguments.iter().map(|arg| {
 2029                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2030                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2031                } else {
 2032                    arg.replace("{buffer_path}", "Untitled")
 2033                }
 2034            }));
 2035        }
 2036
 2037        let mut child = child
 2038            .stdin(smol::process::Stdio::piped())
 2039            .stdout(smol::process::Stdio::piped())
 2040            .stderr(smol::process::Stdio::piped())
 2041            .spawn()?;
 2042
 2043        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2044        let text = buffer
 2045            .handle
 2046            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2047        for chunk in text.chunks() {
 2048            stdin.write_all(chunk.as_bytes()).await?;
 2049        }
 2050        stdin.flush().await?;
 2051
 2052        let output = child.output().await?;
 2053        anyhow::ensure!(
 2054            output.status.success(),
 2055            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2056            output.status.code(),
 2057            String::from_utf8_lossy(&output.stdout),
 2058            String::from_utf8_lossy(&output.stderr),
 2059        );
 2060
 2061        let stdout = String::from_utf8(output.stdout)?;
 2062        Ok(Some(
 2063            buffer
 2064                .handle
 2065                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2066                .await,
 2067        ))
 2068    }
 2069
 2070    async fn try_resolve_code_action(
 2071        lang_server: &LanguageServer,
 2072        action: &mut CodeAction,
 2073    ) -> anyhow::Result<()> {
 2074        match &mut action.lsp_action {
 2075            LspAction::Action(lsp_action) => {
 2076                if !action.resolved
 2077                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2078                    && lsp_action.data.is_some()
 2079                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2080                {
 2081                    *lsp_action = Box::new(
 2082                        lang_server
 2083                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2084                            .await
 2085                            .into_response()?,
 2086                    );
 2087                }
 2088            }
 2089            LspAction::CodeLens(lens) => {
 2090                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2091                    *lens = lang_server
 2092                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2093                        .await
 2094                        .into_response()?;
 2095                }
 2096            }
 2097            LspAction::Command(_) => {}
 2098        }
 2099
 2100        action.resolved = true;
 2101        anyhow::Ok(())
 2102    }
 2103
 2104    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2105        let buffer = buffer_handle.read(cx);
 2106
 2107        let file = buffer.file().cloned();
 2108
 2109        let Some(file) = File::from_dyn(file.as_ref()) else {
 2110            return;
 2111        };
 2112        if !file.is_local() {
 2113            return;
 2114        }
 2115        let path = ProjectPath::from_file(file, cx);
 2116        let worktree_id = file.worktree_id(cx);
 2117        let language = buffer.language().cloned();
 2118
 2119        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2120            for (server_id, diagnostics) in
 2121                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2122            {
 2123                self.update_buffer_diagnostics(
 2124                    buffer_handle,
 2125                    server_id,
 2126                    None,
 2127                    None,
 2128                    diagnostics,
 2129                    Vec::new(),
 2130                    cx,
 2131                )
 2132                .log_err();
 2133            }
 2134        }
 2135        let Some(language) = language else {
 2136            return;
 2137        };
 2138        let Some(snapshot) = self
 2139            .worktree_store
 2140            .read(cx)
 2141            .worktree_for_id(worktree_id, cx)
 2142            .map(|worktree| worktree.read(cx).snapshot())
 2143        else {
 2144            return;
 2145        };
 2146        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2147
 2148        for server_id in
 2149            self.lsp_tree
 2150                .get(path, language.name(), language.manifest(), &delegate, cx)
 2151        {
 2152            let server = self
 2153                .language_servers
 2154                .get(&server_id)
 2155                .and_then(|server_state| {
 2156                    if let LanguageServerState::Running { server, .. } = server_state {
 2157                        Some(server.clone())
 2158                    } else {
 2159                        None
 2160                    }
 2161                });
 2162            let server = match server {
 2163                Some(server) => server,
 2164                None => continue,
 2165            };
 2166
 2167            buffer_handle.update(cx, |buffer, cx| {
 2168                buffer.set_completion_triggers(
 2169                    server.server_id(),
 2170                    server
 2171                        .capabilities()
 2172                        .completion_provider
 2173                        .as_ref()
 2174                        .and_then(|provider| {
 2175                            provider
 2176                                .trigger_characters
 2177                                .as_ref()
 2178                                .map(|characters| characters.iter().cloned().collect())
 2179                        })
 2180                        .unwrap_or_default(),
 2181                    cx,
 2182                );
 2183            });
 2184        }
 2185    }
 2186
 2187    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2188        buffer.update(cx, |buffer, cx| {
 2189            let Some(language) = buffer.language() else {
 2190                return;
 2191            };
 2192            let path = ProjectPath {
 2193                worktree_id: old_file.worktree_id(cx),
 2194                path: old_file.path.clone(),
 2195            };
 2196            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2197                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2198                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2199            }
 2200        });
 2201    }
 2202
 2203    fn update_buffer_diagnostics(
 2204        &mut self,
 2205        buffer: &Entity<Buffer>,
 2206        server_id: LanguageServerId,
 2207        result_id: Option<String>,
 2208        version: Option<i32>,
 2209        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2210        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2211        cx: &mut Context<LspStore>,
 2212    ) -> Result<()> {
 2213        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2214            Ordering::Equal
 2215                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2216                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2217                .then_with(|| a.severity.cmp(&b.severity))
 2218                .then_with(|| a.message.cmp(&b.message))
 2219        }
 2220
 2221        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2222        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2223        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2224
 2225        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2226            Ordering::Equal
 2227                .then_with(|| a.range.start.cmp(&b.range.start))
 2228                .then_with(|| b.range.end.cmp(&a.range.end))
 2229                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2230        });
 2231
 2232        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2233
 2234        let edits_since_save = std::cell::LazyCell::new(|| {
 2235            let saved_version = buffer.read(cx).saved_version();
 2236            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2237        });
 2238
 2239        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2240
 2241        for (new_diagnostic, entry) in diagnostics {
 2242            let start;
 2243            let end;
 2244            if new_diagnostic && entry.diagnostic.is_disk_based {
 2245                // Some diagnostics are based on files on disk instead of buffers'
 2246                // current contents. Adjust these diagnostics' ranges to reflect
 2247                // any unsaved edits.
 2248                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2249                // and were properly adjusted on reuse.
 2250                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2251                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2252            } else {
 2253                start = entry.range.start;
 2254                end = entry.range.end;
 2255            }
 2256
 2257            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2258                ..snapshot.clip_point_utf16(end, Bias::Right);
 2259
 2260            // Expand empty ranges by one codepoint
 2261            if range.start == range.end {
 2262                // This will be go to the next boundary when being clipped
 2263                range.end.column += 1;
 2264                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2265                if range.start == range.end && range.end.column > 0 {
 2266                    range.start.column -= 1;
 2267                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2268                }
 2269            }
 2270
 2271            sanitized_diagnostics.push(DiagnosticEntry {
 2272                range,
 2273                diagnostic: entry.diagnostic,
 2274            });
 2275        }
 2276        drop(edits_since_save);
 2277
 2278        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2279        buffer.update(cx, |buffer, cx| {
 2280            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2281                self.buffer_pull_diagnostics_result_ids
 2282                    .entry(server_id)
 2283                    .or_default()
 2284                    .insert(abs_path, result_id);
 2285            }
 2286
 2287            buffer.update_diagnostics(server_id, set, cx)
 2288        });
 2289
 2290        Ok(())
 2291    }
 2292
 2293    fn register_language_server_for_invisible_worktree(
 2294        &mut self,
 2295        worktree: &Entity<Worktree>,
 2296        language_server_id: LanguageServerId,
 2297        cx: &mut App,
 2298    ) {
 2299        let worktree = worktree.read(cx);
 2300        let worktree_id = worktree.id();
 2301        debug_assert!(!worktree.is_visible());
 2302        let Some(mut origin_seed) = self
 2303            .language_server_ids
 2304            .iter()
 2305            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2306        else {
 2307            return;
 2308        };
 2309        origin_seed.worktree_id = worktree_id;
 2310        self.language_server_ids
 2311            .entry(origin_seed)
 2312            .or_insert_with(|| UnifiedLanguageServer {
 2313                id: language_server_id,
 2314                project_roots: Default::default(),
 2315            });
 2316    }
 2317
 2318    fn register_buffer_with_language_servers(
 2319        &mut self,
 2320        buffer_handle: &Entity<Buffer>,
 2321        only_register_servers: HashSet<LanguageServerSelector>,
 2322        cx: &mut Context<LspStore>,
 2323    ) {
 2324        let buffer = buffer_handle.read(cx);
 2325        let buffer_id = buffer.remote_id();
 2326
 2327        let Some(file) = File::from_dyn(buffer.file()) else {
 2328            return;
 2329        };
 2330        if !file.is_local() {
 2331            return;
 2332        }
 2333
 2334        let abs_path = file.abs_path(cx);
 2335        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2336            return;
 2337        };
 2338        let initial_snapshot = buffer.text_snapshot();
 2339        let worktree_id = file.worktree_id(cx);
 2340
 2341        let Some(language) = buffer.language().cloned() else {
 2342            return;
 2343        };
 2344        let path: Arc<Path> = file
 2345            .path()
 2346            .parent()
 2347            .map(Arc::from)
 2348            .unwrap_or_else(|| file.path().clone());
 2349        let Some(worktree) = self
 2350            .worktree_store
 2351            .read(cx)
 2352            .worktree_for_id(worktree_id, cx)
 2353        else {
 2354            return;
 2355        };
 2356        let language_name = language.name();
 2357        let (reused, delegate, servers) = self
 2358            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2359            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2360            .unwrap_or_else(|| {
 2361                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2362                let delegate: Arc<dyn ManifestDelegate> =
 2363                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2364
 2365                let servers = self
 2366                    .lsp_tree
 2367                    .walk(
 2368                        ProjectPath { worktree_id, path },
 2369                        language.name(),
 2370                        language.manifest(),
 2371                        &delegate,
 2372                        cx,
 2373                    )
 2374                    .collect::<Vec<_>>();
 2375                (false, lsp_delegate, servers)
 2376            });
 2377        let servers_and_adapters = servers
 2378            .into_iter()
 2379            .filter_map(|server_node| {
 2380                if reused && server_node.server_id().is_none() {
 2381                    return None;
 2382                }
 2383                if !only_register_servers.is_empty() {
 2384                    if let Some(server_id) = server_node.server_id()
 2385                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2386                    {
 2387                        return None;
 2388                    }
 2389                    if let Some(name) = server_node.name()
 2390                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2391                    {
 2392                        return None;
 2393                    }
 2394                }
 2395
 2396                let server_id = server_node.server_id_or_init(|disposition| {
 2397                    let path = &disposition.path;
 2398
 2399                    {
 2400                        let uri =
 2401                            Url::from_file_path(worktree.read(cx).abs_path().join(&path.path));
 2402
 2403                        let server_id = self.get_or_insert_language_server(
 2404                            &worktree,
 2405                            delegate.clone(),
 2406                            disposition,
 2407                            &language_name,
 2408                            cx,
 2409                        );
 2410
 2411                        if let Some(state) = self.language_servers.get(&server_id)
 2412                            && let Ok(uri) = uri
 2413                        {
 2414                            state.add_workspace_folder(uri);
 2415                        };
 2416                        server_id
 2417                    }
 2418                })?;
 2419                let server_state = self.language_servers.get(&server_id)?;
 2420                if let LanguageServerState::Running {
 2421                    server, adapter, ..
 2422                } = server_state
 2423                {
 2424                    Some((server.clone(), adapter.clone()))
 2425                } else {
 2426                    None
 2427                }
 2428            })
 2429            .collect::<Vec<_>>();
 2430        for (server, adapter) in servers_and_adapters {
 2431            buffer_handle.update(cx, |buffer, cx| {
 2432                buffer.set_completion_triggers(
 2433                    server.server_id(),
 2434                    server
 2435                        .capabilities()
 2436                        .completion_provider
 2437                        .as_ref()
 2438                        .and_then(|provider| {
 2439                            provider
 2440                                .trigger_characters
 2441                                .as_ref()
 2442                                .map(|characters| characters.iter().cloned().collect())
 2443                        })
 2444                        .unwrap_or_default(),
 2445                    cx,
 2446                );
 2447            });
 2448
 2449            let snapshot = LspBufferSnapshot {
 2450                version: 0,
 2451                snapshot: initial_snapshot.clone(),
 2452            };
 2453
 2454            let mut registered = false;
 2455            self.buffer_snapshots
 2456                .entry(buffer_id)
 2457                .or_default()
 2458                .entry(server.server_id())
 2459                .or_insert_with(|| {
 2460                    registered = true;
 2461                    server.register_buffer(
 2462                        uri.clone(),
 2463                        adapter.language_id(&language.name()),
 2464                        0,
 2465                        initial_snapshot.text(),
 2466                    );
 2467
 2468                    vec![snapshot]
 2469                });
 2470
 2471            self.buffers_opened_in_servers
 2472                .entry(buffer_id)
 2473                .or_default()
 2474                .insert(server.server_id());
 2475            if registered {
 2476                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2477                    language_server_id: server.server_id(),
 2478                    name: None,
 2479                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2480                        proto::RegisteredForBuffer {
 2481                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2482                            buffer_id: buffer_id.to_proto(),
 2483                        },
 2484                    ),
 2485                });
 2486            }
 2487        }
 2488    }
 2489
 2490    fn reuse_existing_language_server<'lang_name>(
 2491        &self,
 2492        server_tree: &LanguageServerTree,
 2493        worktree: &Entity<Worktree>,
 2494        language_name: &'lang_name LanguageName,
 2495        cx: &mut App,
 2496    ) -> Option<(
 2497        Arc<LocalLspAdapterDelegate>,
 2498        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2499    )> {
 2500        if worktree.read(cx).is_visible() {
 2501            return None;
 2502        }
 2503
 2504        let worktree_store = self.worktree_store.read(cx);
 2505        let servers = server_tree
 2506            .instances
 2507            .iter()
 2508            .filter(|(worktree_id, _)| {
 2509                worktree_store
 2510                    .worktree_for_id(**worktree_id, cx)
 2511                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2512            })
 2513            .flat_map(|(worktree_id, servers)| {
 2514                servers
 2515                    .roots
 2516                    .iter()
 2517                    .flat_map(|(_, language_servers)| language_servers)
 2518                    .map(move |(_, (server_node, server_languages))| {
 2519                        (worktree_id, server_node, server_languages)
 2520                    })
 2521                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2522                    .map(|(worktree_id, server_node, _)| {
 2523                        (
 2524                            *worktree_id,
 2525                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2526                        )
 2527                    })
 2528            })
 2529            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2530                acc.entry(worktree_id)
 2531                    .or_insert_with(Vec::new)
 2532                    .push(server_node);
 2533                acc
 2534            })
 2535            .into_values()
 2536            .max_by_key(|servers| servers.len())?;
 2537
 2538        let worktree_id = worktree.read(cx).id();
 2539        let apply = move |tree: &mut LanguageServerTree| {
 2540            for server_node in &servers {
 2541                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2542            }
 2543            servers
 2544        };
 2545
 2546        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2547        Some((delegate, apply))
 2548    }
 2549
 2550    pub(crate) fn unregister_old_buffer_from_language_servers(
 2551        &mut self,
 2552        buffer: &Entity<Buffer>,
 2553        old_file: &File,
 2554        cx: &mut App,
 2555    ) {
 2556        let old_path = match old_file.as_local() {
 2557            Some(local) => local.abs_path(cx),
 2558            None => return,
 2559        };
 2560
 2561        let Ok(file_url) = lsp::Url::from_file_path(old_path.as_path()) else {
 2562            debug_panic!(
 2563                "`{}` is not parseable as an URI",
 2564                old_path.to_string_lossy()
 2565            );
 2566            return;
 2567        };
 2568        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2569    }
 2570
 2571    pub(crate) fn unregister_buffer_from_language_servers(
 2572        &mut self,
 2573        buffer: &Entity<Buffer>,
 2574        file_url: &lsp::Url,
 2575        cx: &mut App,
 2576    ) {
 2577        buffer.update(cx, |buffer, cx| {
 2578            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2579
 2580            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2581                language_server.unregister_buffer(file_url.clone());
 2582            }
 2583        });
 2584    }
 2585
 2586    fn buffer_snapshot_for_lsp_version(
 2587        &mut self,
 2588        buffer: &Entity<Buffer>,
 2589        server_id: LanguageServerId,
 2590        version: Option<i32>,
 2591        cx: &App,
 2592    ) -> Result<TextBufferSnapshot> {
 2593        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2594
 2595        if let Some(version) = version {
 2596            let buffer_id = buffer.read(cx).remote_id();
 2597            let snapshots = if let Some(snapshots) = self
 2598                .buffer_snapshots
 2599                .get_mut(&buffer_id)
 2600                .and_then(|m| m.get_mut(&server_id))
 2601            {
 2602                snapshots
 2603            } else if version == 0 {
 2604                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2605                // We detect this case and treat it as if the version was `None`.
 2606                return Ok(buffer.read(cx).text_snapshot());
 2607            } else {
 2608                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2609            };
 2610
 2611            let found_snapshot = snapshots
 2612                    .binary_search_by_key(&version, |e| e.version)
 2613                    .map(|ix| snapshots[ix].snapshot.clone())
 2614                    .map_err(|_| {
 2615                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2616                    })?;
 2617
 2618            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2619            Ok(found_snapshot)
 2620        } else {
 2621            Ok((buffer.read(cx)).text_snapshot())
 2622        }
 2623    }
 2624
 2625    async fn get_server_code_actions_from_action_kinds(
 2626        lsp_store: &WeakEntity<LspStore>,
 2627        language_server_id: LanguageServerId,
 2628        code_action_kinds: Vec<lsp::CodeActionKind>,
 2629        buffer: &Entity<Buffer>,
 2630        cx: &mut AsyncApp,
 2631    ) -> Result<Vec<CodeAction>> {
 2632        let actions = lsp_store
 2633            .update(cx, move |this, cx| {
 2634                let request = GetCodeActions {
 2635                    range: text::Anchor::MIN..text::Anchor::MAX,
 2636                    kinds: Some(code_action_kinds),
 2637                };
 2638                let server = LanguageServerToQuery::Other(language_server_id);
 2639                this.request_lsp(buffer.clone(), server, request, cx)
 2640            })?
 2641            .await?;
 2642        Ok(actions)
 2643    }
 2644
 2645    pub async fn execute_code_actions_on_server(
 2646        lsp_store: &WeakEntity<LspStore>,
 2647        language_server: &Arc<LanguageServer>,
 2648
 2649        actions: Vec<CodeAction>,
 2650        push_to_history: bool,
 2651        project_transaction: &mut ProjectTransaction,
 2652        cx: &mut AsyncApp,
 2653    ) -> anyhow::Result<()> {
 2654        for mut action in actions {
 2655            Self::try_resolve_code_action(language_server, &mut action)
 2656                .await
 2657                .context("resolving a formatting code action")?;
 2658
 2659            if let Some(edit) = action.lsp_action.edit() {
 2660                if edit.changes.is_none() && edit.document_changes.is_none() {
 2661                    continue;
 2662                }
 2663
 2664                let new = Self::deserialize_workspace_edit(
 2665                    lsp_store.upgrade().context("project dropped")?,
 2666                    edit.clone(),
 2667                    push_to_history,
 2668                    language_server.clone(),
 2669                    cx,
 2670                )
 2671                .await?;
 2672                project_transaction.0.extend(new.0);
 2673            }
 2674
 2675            if let Some(command) = action.lsp_action.command() {
 2676                let server_capabilities = language_server.capabilities();
 2677                let available_commands = server_capabilities
 2678                    .execute_command_provider
 2679                    .as_ref()
 2680                    .map(|options| options.commands.as_slice())
 2681                    .unwrap_or_default();
 2682                if available_commands.contains(&command.command) {
 2683                    lsp_store.update(cx, |lsp_store, _| {
 2684                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2685                            mode.last_workspace_edits_by_language_server
 2686                                .remove(&language_server.server_id());
 2687                        }
 2688                    })?;
 2689
 2690                    language_server
 2691                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2692                            command: command.command.clone(),
 2693                            arguments: command.arguments.clone().unwrap_or_default(),
 2694                            ..Default::default()
 2695                        })
 2696                        .await
 2697                        .into_response()
 2698                        .context("execute command")?;
 2699
 2700                    lsp_store.update(cx, |this, _| {
 2701                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2702                            project_transaction.0.extend(
 2703                                mode.last_workspace_edits_by_language_server
 2704                                    .remove(&language_server.server_id())
 2705                                    .unwrap_or_default()
 2706                                    .0,
 2707                            )
 2708                        }
 2709                    })?;
 2710                } else {
 2711                    log::warn!(
 2712                        "Cannot execute a command {} not listed in the language server capabilities",
 2713                        command.command
 2714                    )
 2715                }
 2716            }
 2717        }
 2718        Ok(())
 2719    }
 2720
 2721    pub async fn deserialize_text_edits(
 2722        this: Entity<LspStore>,
 2723        buffer_to_edit: Entity<Buffer>,
 2724        edits: Vec<lsp::TextEdit>,
 2725        push_to_history: bool,
 2726        _: Arc<CachedLspAdapter>,
 2727        language_server: Arc<LanguageServer>,
 2728        cx: &mut AsyncApp,
 2729    ) -> Result<Option<Transaction>> {
 2730        let edits = this
 2731            .update(cx, |this, cx| {
 2732                this.as_local_mut().unwrap().edits_from_lsp(
 2733                    &buffer_to_edit,
 2734                    edits,
 2735                    language_server.server_id(),
 2736                    None,
 2737                    cx,
 2738                )
 2739            })?
 2740            .await?;
 2741
 2742        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2743            buffer.finalize_last_transaction();
 2744            buffer.start_transaction();
 2745            for (range, text) in edits {
 2746                buffer.edit([(range, text)], None, cx);
 2747            }
 2748
 2749            if buffer.end_transaction(cx).is_some() {
 2750                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2751                if !push_to_history {
 2752                    buffer.forget_transaction(transaction.id);
 2753                }
 2754                Some(transaction)
 2755            } else {
 2756                None
 2757            }
 2758        })?;
 2759
 2760        Ok(transaction)
 2761    }
 2762
 2763    #[allow(clippy::type_complexity)]
 2764    pub(crate) fn edits_from_lsp(
 2765        &mut self,
 2766        buffer: &Entity<Buffer>,
 2767        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2768        server_id: LanguageServerId,
 2769        version: Option<i32>,
 2770        cx: &mut Context<LspStore>,
 2771    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2772        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2773        cx.background_spawn(async move {
 2774            let snapshot = snapshot?;
 2775            let mut lsp_edits = lsp_edits
 2776                .into_iter()
 2777                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2778                .collect::<Vec<_>>();
 2779
 2780            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2781
 2782            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2783            let mut edits = Vec::new();
 2784            while let Some((range, mut new_text)) = lsp_edits.next() {
 2785                // Clip invalid ranges provided by the language server.
 2786                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2787                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2788
 2789                // Combine any LSP edits that are adjacent.
 2790                //
 2791                // Also, combine LSP edits that are separated from each other by only
 2792                // a newline. This is important because for some code actions,
 2793                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2794                // are separated by unchanged newline characters.
 2795                //
 2796                // In order for the diffing logic below to work properly, any edits that
 2797                // cancel each other out must be combined into one.
 2798                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2799                    if next_range.start.0 > range.end {
 2800                        if next_range.start.0.row > range.end.row + 1
 2801                            || next_range.start.0.column > 0
 2802                            || snapshot.clip_point_utf16(
 2803                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2804                                Bias::Left,
 2805                            ) > range.end
 2806                        {
 2807                            break;
 2808                        }
 2809                        new_text.push('\n');
 2810                    }
 2811                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2812                    new_text.push_str(next_text);
 2813                    lsp_edits.next();
 2814                }
 2815
 2816                // For multiline edits, perform a diff of the old and new text so that
 2817                // we can identify the changes more precisely, preserving the locations
 2818                // of any anchors positioned in the unchanged regions.
 2819                if range.end.row > range.start.row {
 2820                    let offset = range.start.to_offset(&snapshot);
 2821                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2822                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2823                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2824                        (
 2825                            snapshot.anchor_after(offset + range.start)
 2826                                ..snapshot.anchor_before(offset + range.end),
 2827                            replacement,
 2828                        )
 2829                    }));
 2830                } else if range.end == range.start {
 2831                    let anchor = snapshot.anchor_after(range.start);
 2832                    edits.push((anchor..anchor, new_text.into()));
 2833                } else {
 2834                    let edit_start = snapshot.anchor_after(range.start);
 2835                    let edit_end = snapshot.anchor_before(range.end);
 2836                    edits.push((edit_start..edit_end, new_text.into()));
 2837                }
 2838            }
 2839
 2840            Ok(edits)
 2841        })
 2842    }
 2843
 2844    pub(crate) async fn deserialize_workspace_edit(
 2845        this: Entity<LspStore>,
 2846        edit: lsp::WorkspaceEdit,
 2847        push_to_history: bool,
 2848        language_server: Arc<LanguageServer>,
 2849        cx: &mut AsyncApp,
 2850    ) -> Result<ProjectTransaction> {
 2851        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2852
 2853        let mut operations = Vec::new();
 2854        if let Some(document_changes) = edit.document_changes {
 2855            match document_changes {
 2856                lsp::DocumentChanges::Edits(edits) => {
 2857                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2858                }
 2859                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2860            }
 2861        } else if let Some(changes) = edit.changes {
 2862            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2863                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2864                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2865                        uri,
 2866                        version: None,
 2867                    },
 2868                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2869                })
 2870            }));
 2871        }
 2872
 2873        let mut project_transaction = ProjectTransaction::default();
 2874        for operation in operations {
 2875            match operation {
 2876                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2877                    let abs_path = op
 2878                        .uri
 2879                        .to_file_path()
 2880                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2881
 2882                    if let Some(parent_path) = abs_path.parent() {
 2883                        fs.create_dir(parent_path).await?;
 2884                    }
 2885                    if abs_path.ends_with("/") {
 2886                        fs.create_dir(&abs_path).await?;
 2887                    } else {
 2888                        fs.create_file(
 2889                            &abs_path,
 2890                            op.options
 2891                                .map(|options| fs::CreateOptions {
 2892                                    overwrite: options.overwrite.unwrap_or(false),
 2893                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2894                                })
 2895                                .unwrap_or_default(),
 2896                        )
 2897                        .await?;
 2898                    }
 2899                }
 2900
 2901                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2902                    let source_abs_path = op
 2903                        .old_uri
 2904                        .to_file_path()
 2905                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2906                    let target_abs_path = op
 2907                        .new_uri
 2908                        .to_file_path()
 2909                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2910                    fs.rename(
 2911                        &source_abs_path,
 2912                        &target_abs_path,
 2913                        op.options
 2914                            .map(|options| fs::RenameOptions {
 2915                                overwrite: options.overwrite.unwrap_or(false),
 2916                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2917                            })
 2918                            .unwrap_or_default(),
 2919                    )
 2920                    .await?;
 2921                }
 2922
 2923                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2924                    let abs_path = op
 2925                        .uri
 2926                        .to_file_path()
 2927                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2928                    let options = op
 2929                        .options
 2930                        .map(|options| fs::RemoveOptions {
 2931                            recursive: options.recursive.unwrap_or(false),
 2932                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2933                        })
 2934                        .unwrap_or_default();
 2935                    if abs_path.ends_with("/") {
 2936                        fs.remove_dir(&abs_path, options).await?;
 2937                    } else {
 2938                        fs.remove_file(&abs_path, options).await?;
 2939                    }
 2940                }
 2941
 2942                lsp::DocumentChangeOperation::Edit(op) => {
 2943                    let buffer_to_edit = this
 2944                        .update(cx, |this, cx| {
 2945                            this.open_local_buffer_via_lsp(
 2946                                op.text_document.uri.clone(),
 2947                                language_server.server_id(),
 2948                                cx,
 2949                            )
 2950                        })?
 2951                        .await?;
 2952
 2953                    let edits = this
 2954                        .update(cx, |this, cx| {
 2955                            let path = buffer_to_edit.read(cx).project_path(cx);
 2956                            let active_entry = this.active_entry;
 2957                            let is_active_entry = path.is_some_and(|project_path| {
 2958                                this.worktree_store
 2959                                    .read(cx)
 2960                                    .entry_for_path(&project_path, cx)
 2961                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2962                            });
 2963                            let local = this.as_local_mut().unwrap();
 2964
 2965                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2966                            for edit in op.edits {
 2967                                match edit {
 2968                                    Edit::Plain(edit) => {
 2969                                        if !edits.contains(&edit) {
 2970                                            edits.push(edit)
 2971                                        }
 2972                                    }
 2973                                    Edit::Annotated(edit) => {
 2974                                        if !edits.contains(&edit.text_edit) {
 2975                                            edits.push(edit.text_edit)
 2976                                        }
 2977                                    }
 2978                                    Edit::Snippet(edit) => {
 2979                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2980                                        else {
 2981                                            continue;
 2982                                        };
 2983
 2984                                        if is_active_entry {
 2985                                            snippet_edits.push((edit.range, snippet));
 2986                                        } else {
 2987                                            // Since this buffer is not focused, apply a normal edit.
 2988                                            let new_edit = TextEdit {
 2989                                                range: edit.range,
 2990                                                new_text: snippet.text,
 2991                                            };
 2992                                            if !edits.contains(&new_edit) {
 2993                                                edits.push(new_edit);
 2994                                            }
 2995                                        }
 2996                                    }
 2997                                }
 2998                            }
 2999                            if !snippet_edits.is_empty() {
 3000                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3001                                let version = if let Some(buffer_version) = op.text_document.version
 3002                                {
 3003                                    local
 3004                                        .buffer_snapshot_for_lsp_version(
 3005                                            &buffer_to_edit,
 3006                                            language_server.server_id(),
 3007                                            Some(buffer_version),
 3008                                            cx,
 3009                                        )
 3010                                        .ok()
 3011                                        .map(|snapshot| snapshot.version)
 3012                                } else {
 3013                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3014                                };
 3015
 3016                                let most_recent_edit = version.and_then(|version| {
 3017                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3018                                });
 3019                                // Check if the edit that triggered that edit has been made by this participant.
 3020
 3021                                if let Some(most_recent_edit) = most_recent_edit {
 3022                                    cx.emit(LspStoreEvent::SnippetEdit {
 3023                                        buffer_id,
 3024                                        edits: snippet_edits,
 3025                                        most_recent_edit,
 3026                                    });
 3027                                }
 3028                            }
 3029
 3030                            local.edits_from_lsp(
 3031                                &buffer_to_edit,
 3032                                edits,
 3033                                language_server.server_id(),
 3034                                op.text_document.version,
 3035                                cx,
 3036                            )
 3037                        })?
 3038                        .await?;
 3039
 3040                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3041                        buffer.finalize_last_transaction();
 3042                        buffer.start_transaction();
 3043                        for (range, text) in edits {
 3044                            buffer.edit([(range, text)], None, cx);
 3045                        }
 3046
 3047                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3048                            if push_to_history {
 3049                                buffer.finalize_last_transaction();
 3050                                buffer.get_transaction(transaction_id).cloned()
 3051                            } else {
 3052                                buffer.forget_transaction(transaction_id)
 3053                            }
 3054                        })
 3055                    })?;
 3056                    if let Some(transaction) = transaction {
 3057                        project_transaction.0.insert(buffer_to_edit, transaction);
 3058                    }
 3059                }
 3060            }
 3061        }
 3062
 3063        Ok(project_transaction)
 3064    }
 3065
 3066    async fn on_lsp_workspace_edit(
 3067        this: WeakEntity<LspStore>,
 3068        params: lsp::ApplyWorkspaceEditParams,
 3069        server_id: LanguageServerId,
 3070        cx: &mut AsyncApp,
 3071    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3072        let this = this.upgrade().context("project project closed")?;
 3073        let language_server = this
 3074            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3075            .context("language server not found")?;
 3076        let transaction = Self::deserialize_workspace_edit(
 3077            this.clone(),
 3078            params.edit,
 3079            true,
 3080            language_server.clone(),
 3081            cx,
 3082        )
 3083        .await
 3084        .log_err();
 3085        this.update(cx, |this, _| {
 3086            if let Some(transaction) = transaction {
 3087                this.as_local_mut()
 3088                    .unwrap()
 3089                    .last_workspace_edits_by_language_server
 3090                    .insert(server_id, transaction);
 3091            }
 3092        })?;
 3093        Ok(lsp::ApplyWorkspaceEditResponse {
 3094            applied: true,
 3095            failed_change: None,
 3096            failure_reason: None,
 3097        })
 3098    }
 3099
 3100    fn remove_worktree(
 3101        &mut self,
 3102        id_to_remove: WorktreeId,
 3103        cx: &mut Context<LspStore>,
 3104    ) -> Vec<LanguageServerId> {
 3105        self.diagnostics.remove(&id_to_remove);
 3106        self.prettier_store.update(cx, |prettier_store, cx| {
 3107            prettier_store.remove_worktree(id_to_remove, cx);
 3108        });
 3109
 3110        let mut servers_to_remove = BTreeSet::default();
 3111        let mut servers_to_preserve = HashSet::default();
 3112        for (seed, state) in &self.language_server_ids {
 3113            if seed.worktree_id == id_to_remove {
 3114                servers_to_remove.insert(state.id);
 3115            } else {
 3116                servers_to_preserve.insert(state.id);
 3117            }
 3118        }
 3119        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3120        self.language_server_ids
 3121            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3122        for server_id_to_remove in &servers_to_remove {
 3123            self.language_server_watched_paths
 3124                .remove(server_id_to_remove);
 3125            self.language_server_paths_watched_for_rename
 3126                .remove(server_id_to_remove);
 3127            self.last_workspace_edits_by_language_server
 3128                .remove(server_id_to_remove);
 3129            self.language_servers.remove(server_id_to_remove);
 3130            self.buffer_pull_diagnostics_result_ids
 3131                .remove(server_id_to_remove);
 3132            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3133                buffer_servers.remove(server_id_to_remove);
 3134            }
 3135            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3136        }
 3137        servers_to_remove.into_iter().collect()
 3138    }
 3139
 3140    fn rebuild_watched_paths_inner<'a>(
 3141        &'a self,
 3142        language_server_id: LanguageServerId,
 3143        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3144        cx: &mut Context<LspStore>,
 3145    ) -> LanguageServerWatchedPathsBuilder {
 3146        let worktrees = self
 3147            .worktree_store
 3148            .read(cx)
 3149            .worktrees()
 3150            .filter_map(|worktree| {
 3151                self.language_servers_for_worktree(worktree.read(cx).id())
 3152                    .find(|server| server.server_id() == language_server_id)
 3153                    .map(|_| worktree)
 3154            })
 3155            .collect::<Vec<_>>();
 3156
 3157        let mut worktree_globs = HashMap::default();
 3158        let mut abs_globs = HashMap::default();
 3159        log::trace!(
 3160            "Processing new watcher paths for language server with id {}",
 3161            language_server_id
 3162        );
 3163
 3164        for watcher in watchers {
 3165            if let Some((worktree, literal_prefix, pattern)) =
 3166                self.worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3167            {
 3168                worktree.update(cx, |worktree, _| {
 3169                    if let Some((tree, glob)) =
 3170                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3171                    {
 3172                        tree.add_path_prefix_to_scan(literal_prefix.into());
 3173                        worktree_globs
 3174                            .entry(tree.id())
 3175                            .or_insert_with(GlobSetBuilder::new)
 3176                            .add(glob);
 3177                    }
 3178                });
 3179            } else {
 3180                let (path, pattern) = match &watcher.glob_pattern {
 3181                    lsp::GlobPattern::String(s) => {
 3182                        let watcher_path = SanitizedPath::from(s);
 3183                        let path = glob_literal_prefix(watcher_path.as_path());
 3184                        let pattern = watcher_path
 3185                            .as_path()
 3186                            .strip_prefix(&path)
 3187                            .map(|p| p.to_string_lossy().to_string())
 3188                            .unwrap_or_else(|e| {
 3189                                debug_panic!(
 3190                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3191                                    s,
 3192                                    path.display(),
 3193                                    e
 3194                                );
 3195                                watcher_path.as_path().to_string_lossy().to_string()
 3196                            });
 3197                        (path, pattern)
 3198                    }
 3199                    lsp::GlobPattern::Relative(rp) => {
 3200                        let Ok(mut base_uri) = match &rp.base_uri {
 3201                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3202                            lsp::OneOf::Right(base_uri) => base_uri,
 3203                        }
 3204                        .to_file_path() else {
 3205                            continue;
 3206                        };
 3207
 3208                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3209                        let pattern = Path::new(&rp.pattern)
 3210                            .strip_prefix(&path)
 3211                            .map(|p| p.to_string_lossy().to_string())
 3212                            .unwrap_or_else(|e| {
 3213                                debug_panic!(
 3214                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3215                                    rp.pattern,
 3216                                    path.display(),
 3217                                    e
 3218                                );
 3219                                rp.pattern.clone()
 3220                            });
 3221                        base_uri.push(path);
 3222                        (base_uri, pattern)
 3223                    }
 3224                };
 3225
 3226                if let Some(glob) = Glob::new(&pattern).log_err() {
 3227                    if !path
 3228                        .components()
 3229                        .any(|c| matches!(c, path::Component::Normal(_)))
 3230                    {
 3231                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3232                        // rather than adding a new watcher for `/`.
 3233                        for worktree in &worktrees {
 3234                            worktree_globs
 3235                                .entry(worktree.read(cx).id())
 3236                                .or_insert_with(GlobSetBuilder::new)
 3237                                .add(glob.clone());
 3238                        }
 3239                    } else {
 3240                        abs_globs
 3241                            .entry(path.into())
 3242                            .or_insert_with(GlobSetBuilder::new)
 3243                            .add(glob);
 3244                    }
 3245                }
 3246            }
 3247        }
 3248
 3249        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3250        for (worktree_id, builder) in worktree_globs {
 3251            if let Ok(globset) = builder.build() {
 3252                watch_builder.watch_worktree(worktree_id, globset);
 3253            }
 3254        }
 3255        for (abs_path, builder) in abs_globs {
 3256            if let Ok(globset) = builder.build() {
 3257                watch_builder.watch_abs_path(abs_path, globset);
 3258            }
 3259        }
 3260        watch_builder
 3261    }
 3262
 3263    fn worktree_and_path_for_file_watcher(
 3264        &self,
 3265        worktrees: &[Entity<Worktree>],
 3266        watcher: &FileSystemWatcher,
 3267        cx: &App,
 3268    ) -> Option<(Entity<Worktree>, PathBuf, String)> {
 3269        worktrees.iter().find_map(|worktree| {
 3270            let tree = worktree.read(cx);
 3271            let worktree_root_path = tree.abs_path();
 3272            match &watcher.glob_pattern {
 3273                lsp::GlobPattern::String(s) => {
 3274                    let watcher_path = SanitizedPath::from(s);
 3275                    let relative = watcher_path
 3276                        .as_path()
 3277                        .strip_prefix(&worktree_root_path)
 3278                        .ok()?;
 3279                    let literal_prefix = glob_literal_prefix(relative);
 3280                    Some((
 3281                        worktree.clone(),
 3282                        literal_prefix,
 3283                        relative.to_string_lossy().to_string(),
 3284                    ))
 3285                }
 3286                lsp::GlobPattern::Relative(rp) => {
 3287                    let base_uri = match &rp.base_uri {
 3288                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3289                        lsp::OneOf::Right(base_uri) => base_uri,
 3290                    }
 3291                    .to_file_path()
 3292                    .ok()?;
 3293                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3294                    let mut literal_prefix = relative.to_owned();
 3295                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3296                    Some((worktree.clone(), literal_prefix, rp.pattern.clone()))
 3297                }
 3298            }
 3299        })
 3300    }
 3301
 3302    fn rebuild_watched_paths(
 3303        &mut self,
 3304        language_server_id: LanguageServerId,
 3305        cx: &mut Context<LspStore>,
 3306    ) {
 3307        let Some(watchers) = self
 3308            .language_server_watcher_registrations
 3309            .get(&language_server_id)
 3310        else {
 3311            return;
 3312        };
 3313
 3314        let watch_builder =
 3315            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
 3316        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3317        self.language_server_watched_paths
 3318            .insert(language_server_id, watcher);
 3319
 3320        cx.notify();
 3321    }
 3322
 3323    fn on_lsp_did_change_watched_files(
 3324        &mut self,
 3325        language_server_id: LanguageServerId,
 3326        registration_id: &str,
 3327        params: DidChangeWatchedFilesRegistrationOptions,
 3328        cx: &mut Context<LspStore>,
 3329    ) {
 3330        let registrations = self
 3331            .language_server_watcher_registrations
 3332            .entry(language_server_id)
 3333            .or_default();
 3334
 3335        registrations.insert(registration_id.to_string(), params.watchers);
 3336
 3337        self.rebuild_watched_paths(language_server_id, cx);
 3338    }
 3339
 3340    fn on_lsp_unregister_did_change_watched_files(
 3341        &mut self,
 3342        language_server_id: LanguageServerId,
 3343        registration_id: &str,
 3344        cx: &mut Context<LspStore>,
 3345    ) {
 3346        let registrations = self
 3347            .language_server_watcher_registrations
 3348            .entry(language_server_id)
 3349            .or_default();
 3350
 3351        if registrations.remove(registration_id).is_some() {
 3352            log::info!(
 3353                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3354                language_server_id,
 3355                registration_id
 3356            );
 3357        } else {
 3358            log::warn!(
 3359                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3360                language_server_id,
 3361                registration_id
 3362            );
 3363        }
 3364
 3365        self.rebuild_watched_paths(language_server_id, cx);
 3366    }
 3367
 3368    async fn initialization_options_for_adapter(
 3369        adapter: Arc<dyn LspAdapter>,
 3370        fs: &dyn Fs,
 3371        delegate: &Arc<dyn LspAdapterDelegate>,
 3372    ) -> Result<Option<serde_json::Value>> {
 3373        let Some(mut initialization_config) =
 3374            adapter.clone().initialization_options(fs, delegate).await?
 3375        else {
 3376            return Ok(None);
 3377        };
 3378
 3379        for other_adapter in delegate.registered_lsp_adapters() {
 3380            if other_adapter.name() == adapter.name() {
 3381                continue;
 3382            }
 3383            if let Ok(Some(target_config)) = other_adapter
 3384                .clone()
 3385                .additional_initialization_options(adapter.name(), fs, delegate)
 3386                .await
 3387            {
 3388                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3389            }
 3390        }
 3391
 3392        Ok(Some(initialization_config))
 3393    }
 3394
 3395    fn toolchain_store(&self) -> &Entity<LocalToolchainStore> {
 3396        &self.toolchain_store
 3397    }
 3398
 3399    async fn workspace_configuration_for_adapter(
 3400        adapter: Arc<dyn LspAdapter>,
 3401        fs: &dyn Fs,
 3402        delegate: &Arc<dyn LspAdapterDelegate>,
 3403        toolchain: Option<Toolchain>,
 3404        cx: &mut AsyncApp,
 3405    ) -> Result<serde_json::Value> {
 3406        let mut workspace_config = adapter
 3407            .clone()
 3408            .workspace_configuration(fs, delegate, toolchain, cx)
 3409            .await?;
 3410
 3411        for other_adapter in delegate.registered_lsp_adapters() {
 3412            if other_adapter.name() == adapter.name() {
 3413                continue;
 3414            }
 3415            if let Ok(Some(target_config)) = other_adapter
 3416                .clone()
 3417                .additional_workspace_configuration(adapter.name(), fs, delegate, cx)
 3418                .await
 3419            {
 3420                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3421            }
 3422        }
 3423
 3424        Ok(workspace_config)
 3425    }
 3426
 3427    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3428        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3429            Some(server.clone())
 3430        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3431            Some(Arc::clone(server))
 3432        } else {
 3433            None
 3434        }
 3435    }
 3436}
 3437
 3438fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3439    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3440        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3441            language_server_id: server.server_id(),
 3442            name: Some(server.name()),
 3443            message: proto::update_language_server::Variant::MetadataUpdated(
 3444                proto::ServerMetadataUpdated {
 3445                    capabilities: Some(capabilities),
 3446                },
 3447            ),
 3448        });
 3449    }
 3450}
 3451
 3452#[derive(Debug)]
 3453pub struct FormattableBuffer {
 3454    handle: Entity<Buffer>,
 3455    abs_path: Option<PathBuf>,
 3456    env: Option<HashMap<String, String>>,
 3457    ranges: Option<Vec<Range<Anchor>>>,
 3458}
 3459
 3460pub struct RemoteLspStore {
 3461    upstream_client: Option<AnyProtoClient>,
 3462    upstream_project_id: u64,
 3463}
 3464
 3465pub(crate) enum LspStoreMode {
 3466    Local(LocalLspStore),   // ssh host and collab host
 3467    Remote(RemoteLspStore), // collab guest
 3468}
 3469
 3470impl LspStoreMode {
 3471    fn is_local(&self) -> bool {
 3472        matches!(self, LspStoreMode::Local(_))
 3473    }
 3474}
 3475
 3476pub struct LspStore {
 3477    mode: LspStoreMode,
 3478    last_formatting_failure: Option<String>,
 3479    downstream_client: Option<(AnyProtoClient, u64)>,
 3480    nonce: u128,
 3481    buffer_store: Entity<BufferStore>,
 3482    worktree_store: Entity<WorktreeStore>,
 3483    pub languages: Arc<LanguageRegistry>,
 3484    language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3485    active_entry: Option<ProjectEntryId>,
 3486    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3487    _maintain_buffer_languages: Task<()>,
 3488    diagnostic_summaries:
 3489        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3490    pub(super) lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3491    lsp_document_colors: HashMap<BufferId, DocumentColorData>,
 3492    lsp_code_lens: HashMap<BufferId, CodeLensData>,
 3493}
 3494
 3495#[derive(Debug, Default, Clone)]
 3496pub struct DocumentColors {
 3497    pub colors: HashSet<DocumentColor>,
 3498    pub cache_version: Option<usize>,
 3499}
 3500
 3501type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3502type CodeLensTask = Shared<Task<std::result::Result<Vec<CodeAction>, Arc<anyhow::Error>>>>;
 3503
 3504#[derive(Debug, Default)]
 3505struct DocumentColorData {
 3506    colors_for_version: Global,
 3507    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3508    cache_version: usize,
 3509    colors_update: Option<(Global, DocumentColorTask)>,
 3510}
 3511
 3512#[derive(Debug, Default)]
 3513struct CodeLensData {
 3514    lens_for_version: Global,
 3515    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3516    update: Option<(Global, CodeLensTask)>,
 3517}
 3518
 3519#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 3520pub enum LspFetchStrategy {
 3521    IgnoreCache,
 3522    UseCache { known_cache_version: Option<usize> },
 3523}
 3524
 3525#[derive(Debug)]
 3526pub enum LspStoreEvent {
 3527    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3528    LanguageServerRemoved(LanguageServerId),
 3529    LanguageServerUpdate {
 3530        language_server_id: LanguageServerId,
 3531        name: Option<LanguageServerName>,
 3532        message: proto::update_language_server::Variant,
 3533    },
 3534    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3535    LanguageServerPrompt(LanguageServerPromptRequest),
 3536    LanguageDetected {
 3537        buffer: Entity<Buffer>,
 3538        new_language: Option<Arc<Language>>,
 3539    },
 3540    Notification(String),
 3541    RefreshInlayHints,
 3542    RefreshCodeLens,
 3543    DiagnosticsUpdated {
 3544        server_id: LanguageServerId,
 3545        paths: Vec<ProjectPath>,
 3546    },
 3547    DiskBasedDiagnosticsStarted {
 3548        language_server_id: LanguageServerId,
 3549    },
 3550    DiskBasedDiagnosticsFinished {
 3551        language_server_id: LanguageServerId,
 3552    },
 3553    SnippetEdit {
 3554        buffer_id: BufferId,
 3555        edits: Vec<(lsp::Range, Snippet)>,
 3556        most_recent_edit: clock::Lamport,
 3557    },
 3558}
 3559
 3560#[derive(Clone, Debug, Serialize)]
 3561pub struct LanguageServerStatus {
 3562    pub name: LanguageServerName,
 3563    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3564    pub has_pending_diagnostic_updates: bool,
 3565    progress_tokens: HashSet<String>,
 3566}
 3567
 3568#[derive(Clone, Debug)]
 3569struct CoreSymbol {
 3570    pub language_server_name: LanguageServerName,
 3571    pub source_worktree_id: WorktreeId,
 3572    pub source_language_server_id: LanguageServerId,
 3573    pub path: ProjectPath,
 3574    pub name: String,
 3575    pub kind: lsp::SymbolKind,
 3576    pub range: Range<Unclipped<PointUtf16>>,
 3577    pub signature: [u8; 32],
 3578}
 3579
 3580impl LspStore {
 3581    pub fn init(client: &AnyProtoClient) {
 3582        client.add_entity_request_handler(Self::handle_multi_lsp_query);
 3583        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3584        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3585        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3586        client.add_entity_message_handler(Self::handle_start_language_server);
 3587        client.add_entity_message_handler(Self::handle_update_language_server);
 3588        client.add_entity_message_handler(Self::handle_language_server_log);
 3589        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3590        client.add_entity_request_handler(Self::handle_format_buffers);
 3591        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3592        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3593        client.add_entity_request_handler(Self::handle_apply_code_action);
 3594        client.add_entity_request_handler(Self::handle_inlay_hints);
 3595        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3596        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3597        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3598        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3599        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3600        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3601        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3602        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3603        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3604        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3605        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3606        client.add_entity_request_handler(Self::handle_lsp_command::<GetCodeActions>);
 3607        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3608        client.add_entity_request_handler(Self::handle_lsp_command::<GetHover>);
 3609        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3610        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3611        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3612        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3613        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3614
 3615        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3616        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3617        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3618        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3619        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3620        client.add_entity_request_handler(
 3621            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3622        );
 3623        client.add_entity_request_handler(
 3624            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3625        );
 3626        client.add_entity_request_handler(
 3627            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3628        );
 3629        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentDiagnostics>);
 3630    }
 3631
 3632    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3633        match &self.mode {
 3634            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3635            _ => None,
 3636        }
 3637    }
 3638
 3639    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3640        match &self.mode {
 3641            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3642            _ => None,
 3643        }
 3644    }
 3645
 3646    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3647        match &mut self.mode {
 3648            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3649            _ => None,
 3650        }
 3651    }
 3652
 3653    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3654        match &self.mode {
 3655            LspStoreMode::Remote(RemoteLspStore {
 3656                upstream_client: Some(upstream_client),
 3657                upstream_project_id,
 3658                ..
 3659            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3660
 3661            LspStoreMode::Remote(RemoteLspStore {
 3662                upstream_client: None,
 3663                ..
 3664            }) => None,
 3665            LspStoreMode::Local(_) => None,
 3666        }
 3667    }
 3668
 3669    pub fn new_local(
 3670        buffer_store: Entity<BufferStore>,
 3671        worktree_store: Entity<WorktreeStore>,
 3672        prettier_store: Entity<PrettierStore>,
 3673        toolchain_store: Entity<LocalToolchainStore>,
 3674        environment: Entity<ProjectEnvironment>,
 3675        manifest_tree: Entity<ManifestTree>,
 3676        languages: Arc<LanguageRegistry>,
 3677        http_client: Arc<dyn HttpClient>,
 3678        fs: Arc<dyn Fs>,
 3679        cx: &mut Context<Self>,
 3680    ) -> Self {
 3681        let yarn = YarnPathStore::new(fs.clone(), cx);
 3682        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3683            .detach();
 3684        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3685            .detach();
 3686        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3687            .detach();
 3688        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3689            .detach();
 3690        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
 3691            cx.subscribe(
 3692                extension_events,
 3693                Self::reload_zed_json_schemas_on_extensions_changed,
 3694            )
 3695            .detach();
 3696        } else {
 3697            log::debug!("No extension events global found. Skipping JSON schema auto-reload setup");
 3698        }
 3699        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3700            .detach();
 3701        subscribe_to_binary_statuses(&languages, cx).detach();
 3702
 3703        let _maintain_workspace_config = {
 3704            let (sender, receiver) = watch::channel();
 3705            (
 3706                Self::maintain_workspace_config(fs.clone(), receiver, cx),
 3707                sender,
 3708            )
 3709        };
 3710
 3711        Self {
 3712            mode: LspStoreMode::Local(LocalLspStore {
 3713                weak: cx.weak_entity(),
 3714                worktree_store: worktree_store.clone(),
 3715
 3716                supplementary_language_servers: Default::default(),
 3717                languages: languages.clone(),
 3718                language_server_ids: Default::default(),
 3719                language_servers: Default::default(),
 3720                last_workspace_edits_by_language_server: Default::default(),
 3721                language_server_watched_paths: Default::default(),
 3722                language_server_paths_watched_for_rename: Default::default(),
 3723                language_server_watcher_registrations: Default::default(),
 3724                buffers_being_formatted: Default::default(),
 3725                buffer_snapshots: Default::default(),
 3726                prettier_store,
 3727                environment,
 3728                http_client,
 3729                fs,
 3730                yarn,
 3731                next_diagnostic_group_id: Default::default(),
 3732                diagnostics: Default::default(),
 3733                _subscription: cx.on_app_quit(|this, cx| {
 3734                    this.as_local_mut()
 3735                        .unwrap()
 3736                        .shutdown_language_servers_on_quit(cx)
 3737                }),
 3738                lsp_tree: LanguageServerTree::new(
 3739                    manifest_tree,
 3740                    languages.clone(),
 3741                    toolchain_store.clone(),
 3742                ),
 3743                toolchain_store,
 3744                registered_buffers: HashMap::default(),
 3745                buffers_opened_in_servers: HashMap::default(),
 3746                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3747                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3748                    .manifest_file_names(),
 3749            }),
 3750            last_formatting_failure: None,
 3751            downstream_client: None,
 3752            buffer_store,
 3753            worktree_store,
 3754            languages: languages.clone(),
 3755            language_server_statuses: Default::default(),
 3756            nonce: StdRng::from_entropy().r#gen(),
 3757            diagnostic_summaries: HashMap::default(),
 3758            lsp_server_capabilities: HashMap::default(),
 3759            lsp_document_colors: HashMap::default(),
 3760            lsp_code_lens: HashMap::default(),
 3761            active_entry: None,
 3762            _maintain_workspace_config,
 3763            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3764        }
 3765    }
 3766
 3767    fn send_lsp_proto_request<R: LspCommand>(
 3768        &self,
 3769        buffer: Entity<Buffer>,
 3770        client: AnyProtoClient,
 3771        upstream_project_id: u64,
 3772        request: R,
 3773        cx: &mut Context<LspStore>,
 3774    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3775        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3776            return Task::ready(Ok(R::Response::default()));
 3777        }
 3778        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3779        cx.spawn(async move |this, cx| {
 3780            let response = client.request(message).await?;
 3781            let this = this.upgrade().context("project dropped")?;
 3782            request
 3783                .response_from_proto(response, this, buffer, cx.clone())
 3784                .await
 3785        })
 3786    }
 3787
 3788    pub(super) fn new_remote(
 3789        buffer_store: Entity<BufferStore>,
 3790        worktree_store: Entity<WorktreeStore>,
 3791        languages: Arc<LanguageRegistry>,
 3792        upstream_client: AnyProtoClient,
 3793        project_id: u64,
 3794        fs: Arc<dyn Fs>,
 3795        cx: &mut Context<Self>,
 3796    ) -> Self {
 3797        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3798            .detach();
 3799        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3800            .detach();
 3801        subscribe_to_binary_statuses(&languages, cx).detach();
 3802        let _maintain_workspace_config = {
 3803            let (sender, receiver) = watch::channel();
 3804            (Self::maintain_workspace_config(fs, receiver, cx), sender)
 3805        };
 3806        Self {
 3807            mode: LspStoreMode::Remote(RemoteLspStore {
 3808                upstream_client: Some(upstream_client),
 3809                upstream_project_id: project_id,
 3810            }),
 3811            downstream_client: None,
 3812            last_formatting_failure: None,
 3813            buffer_store,
 3814            worktree_store,
 3815            languages: languages.clone(),
 3816            language_server_statuses: Default::default(),
 3817            nonce: StdRng::from_entropy().r#gen(),
 3818            diagnostic_summaries: HashMap::default(),
 3819            lsp_server_capabilities: HashMap::default(),
 3820            lsp_document_colors: HashMap::default(),
 3821            lsp_code_lens: HashMap::default(),
 3822            active_entry: None,
 3823
 3824            _maintain_workspace_config,
 3825            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3826        }
 3827    }
 3828
 3829    fn on_buffer_store_event(
 3830        &mut self,
 3831        _: Entity<BufferStore>,
 3832        event: &BufferStoreEvent,
 3833        cx: &mut Context<Self>,
 3834    ) {
 3835        match event {
 3836            BufferStoreEvent::BufferAdded(buffer) => {
 3837                self.on_buffer_added(buffer, cx).log_err();
 3838            }
 3839            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3840                let buffer_id = buffer.read(cx).remote_id();
 3841                if let Some(local) = self.as_local_mut()
 3842                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3843                {
 3844                    local.reset_buffer(buffer, old_file, cx);
 3845
 3846                    if local.registered_buffers.contains_key(&buffer_id) {
 3847                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3848                    }
 3849                }
 3850
 3851                self.detect_language_for_buffer(buffer, cx);
 3852                if let Some(local) = self.as_local_mut() {
 3853                    local.initialize_buffer(buffer, cx);
 3854                    if local.registered_buffers.contains_key(&buffer_id) {
 3855                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3856                    }
 3857                }
 3858            }
 3859            _ => {}
 3860        }
 3861    }
 3862
 3863    fn on_worktree_store_event(
 3864        &mut self,
 3865        _: Entity<WorktreeStore>,
 3866        event: &WorktreeStoreEvent,
 3867        cx: &mut Context<Self>,
 3868    ) {
 3869        match event {
 3870            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3871                if !worktree.read(cx).is_local() {
 3872                    return;
 3873                }
 3874                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3875                    worktree::Event::UpdatedEntries(changes) => {
 3876                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3877                    }
 3878                    worktree::Event::UpdatedGitRepositories(_)
 3879                    | worktree::Event::DeletedEntry(_) => {}
 3880                })
 3881                .detach()
 3882            }
 3883            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3884            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3885                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3886            }
 3887            WorktreeStoreEvent::WorktreeReleased(..)
 3888            | WorktreeStoreEvent::WorktreeOrderChanged
 3889            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3890            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3891            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3892        }
 3893    }
 3894
 3895    fn on_prettier_store_event(
 3896        &mut self,
 3897        _: Entity<PrettierStore>,
 3898        event: &PrettierStoreEvent,
 3899        cx: &mut Context<Self>,
 3900    ) {
 3901        match event {
 3902            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3903                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3904            }
 3905            PrettierStoreEvent::LanguageServerAdded {
 3906                new_server_id,
 3907                name,
 3908                prettier_server,
 3909            } => {
 3910                self.register_supplementary_language_server(
 3911                    *new_server_id,
 3912                    name.clone(),
 3913                    prettier_server.clone(),
 3914                    cx,
 3915                );
 3916            }
 3917        }
 3918    }
 3919
 3920    fn on_toolchain_store_event(
 3921        &mut self,
 3922        _: Entity<LocalToolchainStore>,
 3923        event: &ToolchainStoreEvent,
 3924        _: &mut Context<Self>,
 3925    ) {
 3926        match event {
 3927            ToolchainStoreEvent::ToolchainActivated => self.request_workspace_config_refresh(),
 3928        }
 3929    }
 3930
 3931    fn request_workspace_config_refresh(&mut self) {
 3932        *self._maintain_workspace_config.1.borrow_mut() = ();
 3933    }
 3934
 3935    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3936        self.as_local().map(|local| local.prettier_store.clone())
 3937    }
 3938
 3939    fn on_buffer_event(
 3940        &mut self,
 3941        buffer: Entity<Buffer>,
 3942        event: &language::BufferEvent,
 3943        cx: &mut Context<Self>,
 3944    ) {
 3945        match event {
 3946            language::BufferEvent::Edited => {
 3947                self.on_buffer_edited(buffer, cx);
 3948            }
 3949
 3950            language::BufferEvent::Saved => {
 3951                self.on_buffer_saved(buffer, cx);
 3952            }
 3953
 3954            _ => {}
 3955        }
 3956    }
 3957
 3958    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3959        buffer
 3960            .read(cx)
 3961            .set_language_registry(self.languages.clone());
 3962
 3963        cx.subscribe(buffer, |this, buffer, event, cx| {
 3964            this.on_buffer_event(buffer, event, cx);
 3965        })
 3966        .detach();
 3967
 3968        self.detect_language_for_buffer(buffer, cx);
 3969        if let Some(local) = self.as_local_mut() {
 3970            local.initialize_buffer(buffer, cx);
 3971        }
 3972
 3973        Ok(())
 3974    }
 3975
 3976    pub fn reload_zed_json_schemas_on_extensions_changed(
 3977        &mut self,
 3978        _: Entity<extension::ExtensionEvents>,
 3979        evt: &extension::Event,
 3980        cx: &mut Context<Self>,
 3981    ) {
 3982        match evt {
 3983            extension::Event::ExtensionInstalled(_)
 3984            | extension::Event::ExtensionUninstalled(_)
 3985            | extension::Event::ConfigureExtensionRequested(_) => return,
 3986            extension::Event::ExtensionsInstalledChanged => {}
 3987        }
 3988        if self.as_local().is_none() {
 3989            return;
 3990        }
 3991        cx.spawn(async move |this, cx| {
 3992            let weak_ref = this.clone();
 3993
 3994            let servers = this
 3995                .update(cx, |this, cx| {
 3996                    let local = this.as_local()?;
 3997
 3998                    let mut servers = Vec::new();
 3999                    for (seed, state) in &local.language_server_ids {
 4000
 4001                            let Some(states) = local.language_servers.get(&state.id) else {
 4002                                continue;
 4003                            };
 4004                            let (json_adapter, json_server) = match states {
 4005                                LanguageServerState::Running {
 4006                                    adapter, server, ..
 4007                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 4008                                    (adapter.adapter.clone(), server.clone())
 4009                                }
 4010                                _ => continue,
 4011                            };
 4012
 4013                            let Some(worktree) = this
 4014                                .worktree_store
 4015                                .read(cx)
 4016                                .worktree_for_id(seed.worktree_id, cx)
 4017                            else {
 4018                                continue;
 4019                            };
 4020                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4021                                LocalLspAdapterDelegate::new(
 4022                                    local.languages.clone(),
 4023                                    &local.environment,
 4024                                    weak_ref.clone(),
 4025                                    &worktree,
 4026                                    local.http_client.clone(),
 4027                                    local.fs.clone(),
 4028                                    cx,
 4029                                );
 4030
 4031                            servers.push((json_adapter, json_server, json_delegate));
 4032
 4033                    }
 4034                    Some(servers)
 4035                })
 4036                .ok()
 4037                .flatten();
 4038
 4039            let Some(servers) = servers else {
 4040                return;
 4041            };
 4042
 4043            let Ok(Some((fs, _))) = this.read_with(cx, |this, _| {
 4044                let local = this.as_local()?;
 4045                let toolchain_store = local.toolchain_store().clone();
 4046                Some((local.fs.clone(), toolchain_store))
 4047            }) else {
 4048                return;
 4049            };
 4050            for (adapter, server, delegate) in servers {
 4051                adapter.clear_zed_json_schema_cache().await;
 4052
 4053                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4054                        adapter,
 4055                        fs.as_ref(),
 4056                        &delegate,
 4057                        None,
 4058                        cx,
 4059                    )
 4060                    .await
 4061                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4062                    .ok()
 4063                else {
 4064                    continue;
 4065                };
 4066                server
 4067                    .notify::<lsp::notification::DidChangeConfiguration>(
 4068                        &lsp::DidChangeConfigurationParams {
 4069                            settings: json_workspace_config,
 4070                        },
 4071                    )
 4072                    .ok();
 4073            }
 4074        })
 4075        .detach();
 4076    }
 4077
 4078    pub(crate) fn register_buffer_with_language_servers(
 4079        &mut self,
 4080        buffer: &Entity<Buffer>,
 4081        only_register_servers: HashSet<LanguageServerSelector>,
 4082        ignore_refcounts: bool,
 4083        cx: &mut Context<Self>,
 4084    ) -> OpenLspBufferHandle {
 4085        let buffer_id = buffer.read(cx).remote_id();
 4086        let handle = cx.new(|_| buffer.clone());
 4087        if let Some(local) = self.as_local_mut() {
 4088            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4089            if !ignore_refcounts {
 4090                *refcount += 1;
 4091            }
 4092
 4093            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4094            // 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
 4095            // 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
 4096            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4097            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4098                return handle;
 4099            };
 4100            if !file.is_local() {
 4101                return handle;
 4102            }
 4103
 4104            if ignore_refcounts || *refcount == 1 {
 4105                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4106            }
 4107            if !ignore_refcounts {
 4108                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4109                    let refcount = {
 4110                        let local = lsp_store.as_local_mut().unwrap();
 4111                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4112                            debug_panic!("bad refcounting");
 4113                            return;
 4114                        };
 4115
 4116                        *refcount -= 1;
 4117                        *refcount
 4118                    };
 4119                    if refcount == 0 {
 4120                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4121                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4122                        let local = lsp_store.as_local_mut().unwrap();
 4123                        local.registered_buffers.remove(&buffer_id);
 4124                        local.buffers_opened_in_servers.remove(&buffer_id);
 4125                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4126                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4127                        }
 4128                    }
 4129                })
 4130                .detach();
 4131            }
 4132        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4133            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4134            cx.background_spawn(async move {
 4135                upstream_client
 4136                    .request(proto::RegisterBufferWithLanguageServers {
 4137                        project_id: upstream_project_id,
 4138                        buffer_id,
 4139                        only_servers: only_register_servers
 4140                            .into_iter()
 4141                            .map(|selector| {
 4142                                let selector = match selector {
 4143                                    LanguageServerSelector::Id(language_server_id) => {
 4144                                        proto::language_server_selector::Selector::ServerId(
 4145                                            language_server_id.to_proto(),
 4146                                        )
 4147                                    }
 4148                                    LanguageServerSelector::Name(language_server_name) => {
 4149                                        proto::language_server_selector::Selector::Name(
 4150                                            language_server_name.to_string(),
 4151                                        )
 4152                                    }
 4153                                };
 4154                                proto::LanguageServerSelector {
 4155                                    selector: Some(selector),
 4156                                }
 4157                            })
 4158                            .collect(),
 4159                    })
 4160                    .await
 4161            })
 4162            .detach();
 4163        } else {
 4164            panic!("oops!");
 4165        }
 4166        handle
 4167    }
 4168
 4169    fn maintain_buffer_languages(
 4170        languages: Arc<LanguageRegistry>,
 4171        cx: &mut Context<Self>,
 4172    ) -> Task<()> {
 4173        let mut subscription = languages.subscribe();
 4174        let mut prev_reload_count = languages.reload_count();
 4175        cx.spawn(async move |this, cx| {
 4176            while let Some(()) = subscription.next().await {
 4177                if let Some(this) = this.upgrade() {
 4178                    // If the language registry has been reloaded, then remove and
 4179                    // re-assign the languages on all open buffers.
 4180                    let reload_count = languages.reload_count();
 4181                    if reload_count > prev_reload_count {
 4182                        prev_reload_count = reload_count;
 4183                        this.update(cx, |this, cx| {
 4184                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4185                                for buffer in buffer_store.buffers() {
 4186                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4187                                    {
 4188                                        buffer
 4189                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4190                                        if let Some(local) = this.as_local_mut() {
 4191                                            local.reset_buffer(&buffer, &f, cx);
 4192
 4193                                            if local
 4194                                                .registered_buffers
 4195                                                .contains_key(&buffer.read(cx).remote_id())
 4196                                                && let Some(file_url) =
 4197                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4198                                            {
 4199                                                local.unregister_buffer_from_language_servers(
 4200                                                    &buffer, &file_url, cx,
 4201                                                );
 4202                                            }
 4203                                        }
 4204                                    }
 4205                                }
 4206                            });
 4207                        })
 4208                        .ok();
 4209                    }
 4210
 4211                    this.update(cx, |this, cx| {
 4212                        let mut plain_text_buffers = Vec::new();
 4213                        let mut buffers_with_unknown_injections = Vec::new();
 4214                        for handle in this.buffer_store.read(cx).buffers() {
 4215                            let buffer = handle.read(cx);
 4216                            if buffer.language().is_none()
 4217                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4218                            {
 4219                                plain_text_buffers.push(handle);
 4220                            } else if buffer.contains_unknown_injections() {
 4221                                buffers_with_unknown_injections.push(handle);
 4222                            }
 4223                        }
 4224
 4225                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4226                        // and reused later in the invisible worktrees.
 4227                        plain_text_buffers.sort_by_key(|buffer| {
 4228                            Reverse(
 4229                                File::from_dyn(buffer.read(cx).file())
 4230                                    .map(|file| file.worktree.read(cx).is_visible()),
 4231                            )
 4232                        });
 4233
 4234                        for buffer in plain_text_buffers {
 4235                            this.detect_language_for_buffer(&buffer, cx);
 4236                            if let Some(local) = this.as_local_mut() {
 4237                                local.initialize_buffer(&buffer, cx);
 4238                                if local
 4239                                    .registered_buffers
 4240                                    .contains_key(&buffer.read(cx).remote_id())
 4241                                {
 4242                                    local.register_buffer_with_language_servers(
 4243                                        &buffer,
 4244                                        HashSet::default(),
 4245                                        cx,
 4246                                    );
 4247                                }
 4248                            }
 4249                        }
 4250
 4251                        for buffer in buffers_with_unknown_injections {
 4252                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4253                        }
 4254                    })
 4255                    .ok();
 4256                }
 4257            }
 4258        })
 4259    }
 4260
 4261    fn detect_language_for_buffer(
 4262        &mut self,
 4263        buffer_handle: &Entity<Buffer>,
 4264        cx: &mut Context<Self>,
 4265    ) -> Option<language::AvailableLanguage> {
 4266        // If the buffer has a language, set it and start the language server if we haven't already.
 4267        let buffer = buffer_handle.read(cx);
 4268        let file = buffer.file()?;
 4269
 4270        let content = buffer.as_rope();
 4271        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4272        if let Some(available_language) = &available_language {
 4273            if let Some(Ok(Ok(new_language))) = self
 4274                .languages
 4275                .load_language(available_language)
 4276                .now_or_never()
 4277            {
 4278                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4279            }
 4280        } else {
 4281            cx.emit(LspStoreEvent::LanguageDetected {
 4282                buffer: buffer_handle.clone(),
 4283                new_language: None,
 4284            });
 4285        }
 4286
 4287        available_language
 4288    }
 4289
 4290    pub(crate) fn set_language_for_buffer(
 4291        &mut self,
 4292        buffer_entity: &Entity<Buffer>,
 4293        new_language: Arc<Language>,
 4294        cx: &mut Context<Self>,
 4295    ) {
 4296        let buffer = buffer_entity.read(cx);
 4297        let buffer_file = buffer.file().cloned();
 4298        let buffer_id = buffer.remote_id();
 4299        if let Some(local_store) = self.as_local_mut()
 4300            && local_store.registered_buffers.contains_key(&buffer_id)
 4301            && let Some(abs_path) =
 4302                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4303            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4304        {
 4305            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4306        }
 4307        buffer_entity.update(cx, |buffer, cx| {
 4308            if buffer
 4309                .language()
 4310                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4311            {
 4312                buffer.set_language(Some(new_language.clone()), cx);
 4313            }
 4314        });
 4315
 4316        let settings =
 4317            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4318        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4319
 4320        let worktree_id = if let Some(file) = buffer_file {
 4321            let worktree = file.worktree.clone();
 4322
 4323            if let Some(local) = self.as_local_mut()
 4324                && local.registered_buffers.contains_key(&buffer_id)
 4325            {
 4326                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4327            }
 4328            Some(worktree.read(cx).id())
 4329        } else {
 4330            None
 4331        };
 4332
 4333        if settings.prettier.allowed
 4334            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4335        {
 4336            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4337            if let Some(prettier_store) = prettier_store {
 4338                prettier_store.update(cx, |prettier_store, cx| {
 4339                    prettier_store.install_default_prettier(
 4340                        worktree_id,
 4341                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4342                        cx,
 4343                    )
 4344                })
 4345            }
 4346        }
 4347
 4348        cx.emit(LspStoreEvent::LanguageDetected {
 4349            buffer: buffer_entity.clone(),
 4350            new_language: Some(new_language),
 4351        })
 4352    }
 4353
 4354    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4355        self.buffer_store.clone()
 4356    }
 4357
 4358    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4359        self.active_entry = active_entry;
 4360    }
 4361
 4362    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4363        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4364            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4365        {
 4366            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4367                summaries
 4368                    .iter()
 4369                    .map(|(server_id, summary)| summary.to_proto(*server_id, path))
 4370            });
 4371            if let Some(summary) = summaries.next() {
 4372                client
 4373                    .send(proto::UpdateDiagnosticSummary {
 4374                        project_id: downstream_project_id,
 4375                        worktree_id: worktree.id().to_proto(),
 4376                        summary: Some(summary),
 4377                        more_summaries: summaries.collect(),
 4378                    })
 4379                    .log_err();
 4380            }
 4381        }
 4382    }
 4383
 4384    // TODO: remove MultiLspQuery: instead, the proto handler should pick appropriate server(s)
 4385    // Then, use `send_lsp_proto_request` or analogue for most of the LSP proto requests and inline this check inside
 4386    fn is_capable_for_proto_request<R>(
 4387        &self,
 4388        buffer: &Entity<Buffer>,
 4389        request: &R,
 4390        cx: &Context<Self>,
 4391    ) -> bool
 4392    where
 4393        R: LspCommand,
 4394    {
 4395        self.check_if_capable_for_proto_request(
 4396            buffer,
 4397            |capabilities| {
 4398                request.check_capabilities(AdapterServerCapabilities {
 4399                    server_capabilities: capabilities.clone(),
 4400                    code_action_kinds: None,
 4401                })
 4402            },
 4403            cx,
 4404        )
 4405    }
 4406
 4407    fn check_if_capable_for_proto_request<F>(
 4408        &self,
 4409        buffer: &Entity<Buffer>,
 4410        check: F,
 4411        cx: &Context<Self>,
 4412    ) -> bool
 4413    where
 4414        F: Fn(&lsp::ServerCapabilities) -> bool,
 4415    {
 4416        let Some(language) = buffer.read(cx).language().cloned() else {
 4417            return false;
 4418        };
 4419        let relevant_language_servers = self
 4420            .languages
 4421            .lsp_adapters(&language.name())
 4422            .into_iter()
 4423            .map(|lsp_adapter| lsp_adapter.name())
 4424            .collect::<HashSet<_>>();
 4425        self.language_server_statuses
 4426            .iter()
 4427            .filter_map(|(server_id, server_status)| {
 4428                relevant_language_servers
 4429                    .contains(&server_status.name)
 4430                    .then_some(server_id)
 4431            })
 4432            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4433            .any(check)
 4434    }
 4435
 4436    pub fn request_lsp<R>(
 4437        &mut self,
 4438        buffer: Entity<Buffer>,
 4439        server: LanguageServerToQuery,
 4440        request: R,
 4441        cx: &mut Context<Self>,
 4442    ) -> Task<Result<R::Response>>
 4443    where
 4444        R: LspCommand,
 4445        <R::LspRequest as lsp::request::Request>::Result: Send,
 4446        <R::LspRequest as lsp::request::Request>::Params: Send,
 4447    {
 4448        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4449            return self.send_lsp_proto_request(
 4450                buffer,
 4451                upstream_client,
 4452                upstream_project_id,
 4453                request,
 4454                cx,
 4455            );
 4456        }
 4457
 4458        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4459            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4460                local
 4461                    .language_servers_for_buffer(buffer, cx)
 4462                    .find(|(_, server)| {
 4463                        request.check_capabilities(server.adapter_server_capabilities())
 4464                    })
 4465                    .map(|(_, server)| server.clone())
 4466            }),
 4467            LanguageServerToQuery::Other(id) => self
 4468                .language_server_for_local_buffer(buffer, id, cx)
 4469                .and_then(|(_, server)| {
 4470                    request
 4471                        .check_capabilities(server.adapter_server_capabilities())
 4472                        .then(|| Arc::clone(server))
 4473                }),
 4474        }) else {
 4475            return Task::ready(Ok(Default::default()));
 4476        };
 4477
 4478        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4479
 4480        let Some(file) = file else {
 4481            return Task::ready(Ok(Default::default()));
 4482        };
 4483
 4484        let lsp_params = match request.to_lsp_params_or_response(
 4485            &file.abs_path(cx),
 4486            buffer.read(cx),
 4487            &language_server,
 4488            cx,
 4489        ) {
 4490            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4491            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4492
 4493            Err(err) => {
 4494                let message = format!(
 4495                    "{} via {} failed: {}",
 4496                    request.display_name(),
 4497                    language_server.name(),
 4498                    err
 4499                );
 4500                log::warn!("{message}");
 4501                return Task::ready(Err(anyhow!(message)));
 4502            }
 4503        };
 4504
 4505        let status = request.status();
 4506        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4507            return Task::ready(Ok(Default::default()));
 4508        }
 4509        cx.spawn(async move |this, cx| {
 4510            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4511
 4512            let id = lsp_request.id();
 4513            let _cleanup = if status.is_some() {
 4514                cx.update(|cx| {
 4515                    this.update(cx, |this, cx| {
 4516                        this.on_lsp_work_start(
 4517                            language_server.server_id(),
 4518                            id.to_string(),
 4519                            LanguageServerProgress {
 4520                                is_disk_based_diagnostics_progress: false,
 4521                                is_cancellable: false,
 4522                                title: None,
 4523                                message: status.clone(),
 4524                                percentage: None,
 4525                                last_update_at: cx.background_executor().now(),
 4526                            },
 4527                            cx,
 4528                        );
 4529                    })
 4530                })
 4531                .log_err();
 4532
 4533                Some(defer(|| {
 4534                    cx.update(|cx| {
 4535                        this.update(cx, |this, cx| {
 4536                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4537                        })
 4538                    })
 4539                    .log_err();
 4540                }))
 4541            } else {
 4542                None
 4543            };
 4544
 4545            let result = lsp_request.await.into_response();
 4546
 4547            let response = result.map_err(|err| {
 4548                let message = format!(
 4549                    "{} via {} failed: {}",
 4550                    request.display_name(),
 4551                    language_server.name(),
 4552                    err
 4553                );
 4554                log::warn!("{message}");
 4555                anyhow::anyhow!(message)
 4556            })?;
 4557
 4558            request
 4559                .response_from_lsp(
 4560                    response,
 4561                    this.upgrade().context("no app context")?,
 4562                    buffer,
 4563                    language_server.server_id(),
 4564                    cx.clone(),
 4565                )
 4566                .await
 4567        })
 4568    }
 4569
 4570    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4571        let mut language_formatters_to_check = Vec::new();
 4572        for buffer in self.buffer_store.read(cx).buffers() {
 4573            let buffer = buffer.read(cx);
 4574            let buffer_file = File::from_dyn(buffer.file());
 4575            let buffer_language = buffer.language();
 4576            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4577            if buffer_language.is_some() {
 4578                language_formatters_to_check.push((
 4579                    buffer_file.map(|f| f.worktree_id(cx)),
 4580                    settings.into_owned(),
 4581                ));
 4582            }
 4583        }
 4584
 4585        self.request_workspace_config_refresh();
 4586
 4587        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4588            prettier_store.update(cx, |prettier_store, cx| {
 4589                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4590            })
 4591        }
 4592
 4593        cx.notify();
 4594    }
 4595
 4596    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4597        let buffer_store = self.buffer_store.clone();
 4598        let Some(local) = self.as_local_mut() else {
 4599            return;
 4600        };
 4601        let mut adapters = BTreeMap::default();
 4602        let get_adapter = {
 4603            let languages = local.languages.clone();
 4604            let environment = local.environment.clone();
 4605            let weak = local.weak.clone();
 4606            let worktree_store = local.worktree_store.clone();
 4607            let http_client = local.http_client.clone();
 4608            let fs = local.fs.clone();
 4609            move |worktree_id, cx: &mut App| {
 4610                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4611                Some(LocalLspAdapterDelegate::new(
 4612                    languages.clone(),
 4613                    &environment,
 4614                    weak.clone(),
 4615                    &worktree,
 4616                    http_client.clone(),
 4617                    fs.clone(),
 4618                    cx,
 4619                ))
 4620            }
 4621        };
 4622
 4623        let mut messages_to_report = Vec::new();
 4624        let (new_tree, to_stop) = {
 4625            let mut rebase = local.lsp_tree.rebase();
 4626            let buffers = buffer_store
 4627                .read(cx)
 4628                .buffers()
 4629                .filter_map(|buffer| {
 4630                    let raw_buffer = buffer.read(cx);
 4631                    if !local
 4632                        .registered_buffers
 4633                        .contains_key(&raw_buffer.remote_id())
 4634                    {
 4635                        return None;
 4636                    }
 4637                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4638                    let language = raw_buffer.language().cloned()?;
 4639                    Some((file, language, raw_buffer.remote_id()))
 4640                })
 4641                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4642
 4643            for (file, language, buffer_id) in buffers {
 4644                let worktree_id = file.worktree_id(cx);
 4645                let Some(worktree) = local
 4646                    .worktree_store
 4647                    .read(cx)
 4648                    .worktree_for_id(worktree_id, cx)
 4649                else {
 4650                    continue;
 4651                };
 4652
 4653                if let Some((_, apply)) = local.reuse_existing_language_server(
 4654                    rebase.server_tree(),
 4655                    &worktree,
 4656                    &language.name(),
 4657                    cx,
 4658                ) {
 4659                    (apply)(rebase.server_tree());
 4660                } else if let Some(lsp_delegate) = adapters
 4661                    .entry(worktree_id)
 4662                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4663                    .clone()
 4664                {
 4665                    let delegate =
 4666                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4667                    let path = file
 4668                        .path()
 4669                        .parent()
 4670                        .map(Arc::from)
 4671                        .unwrap_or_else(|| file.path().clone());
 4672                    let worktree_path = ProjectPath { worktree_id, path };
 4673                    let abs_path = file.abs_path(cx);
 4674                    let worktree_root = worktree.read(cx).abs_path();
 4675                    let nodes = rebase
 4676                        .walk(
 4677                            worktree_path,
 4678                            language.name(),
 4679                            language.manifest(),
 4680                            delegate.clone(),
 4681                            cx,
 4682                        )
 4683                        .collect::<Vec<_>>();
 4684
 4685                    for node in nodes {
 4686                        let server_id = node.server_id_or_init(|disposition| {
 4687                            let path = &disposition.path;
 4688                            let uri = Url::from_file_path(worktree_root.join(&path.path));
 4689                            let key = LanguageServerSeed {
 4690                                worktree_id,
 4691                                name: disposition.server_name.clone(),
 4692                                settings: disposition.settings.clone(),
 4693                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4694                                    path.worktree_id,
 4695                                    &path.path,
 4696                                    language.name(),
 4697                                ),
 4698                            };
 4699                            local.language_server_ids.remove(&key);
 4700
 4701                            let server_id = local.get_or_insert_language_server(
 4702                                &worktree,
 4703                                lsp_delegate.clone(),
 4704                                disposition,
 4705                                &language.name(),
 4706                                cx,
 4707                            );
 4708                            if let Some(state) = local.language_servers.get(&server_id)
 4709                                && let Ok(uri) = uri
 4710                            {
 4711                                state.add_workspace_folder(uri);
 4712                            };
 4713                            server_id
 4714                        });
 4715
 4716                        if let Some(language_server_id) = server_id {
 4717                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4718                                language_server_id,
 4719                                name: node.name(),
 4720                                message:
 4721                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4722                                        proto::RegisteredForBuffer {
 4723                                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 4724                                            buffer_id: buffer_id.to_proto(),
 4725                                        },
 4726                                    ),
 4727                            });
 4728                        }
 4729                    }
 4730                } else {
 4731                    continue;
 4732                }
 4733            }
 4734            rebase.finish()
 4735        };
 4736        for message in messages_to_report {
 4737            cx.emit(message);
 4738        }
 4739        local.lsp_tree = new_tree;
 4740        for (id, _) in to_stop {
 4741            self.stop_local_language_server(id, cx).detach();
 4742        }
 4743    }
 4744
 4745    pub fn apply_code_action(
 4746        &self,
 4747        buffer_handle: Entity<Buffer>,
 4748        mut action: CodeAction,
 4749        push_to_history: bool,
 4750        cx: &mut Context<Self>,
 4751    ) -> Task<Result<ProjectTransaction>> {
 4752        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4753            let request = proto::ApplyCodeAction {
 4754                project_id,
 4755                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4756                action: Some(Self::serialize_code_action(&action)),
 4757            };
 4758            let buffer_store = self.buffer_store();
 4759            cx.spawn(async move |_, cx| {
 4760                let response = upstream_client
 4761                    .request(request)
 4762                    .await?
 4763                    .transaction
 4764                    .context("missing transaction")?;
 4765
 4766                buffer_store
 4767                    .update(cx, |buffer_store, cx| {
 4768                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4769                    })?
 4770                    .await
 4771            })
 4772        } else if self.mode.is_local() {
 4773            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4774                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4775                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4776            }) else {
 4777                return Task::ready(Ok(ProjectTransaction::default()));
 4778            };
 4779            cx.spawn(async move |this,  cx| {
 4780                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4781                    .await
 4782                    .context("resolving a code action")?;
 4783                if let Some(edit) = action.lsp_action.edit()
 4784                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4785                        return LocalLspStore::deserialize_workspace_edit(
 4786                            this.upgrade().context("no app present")?,
 4787                            edit.clone(),
 4788                            push_to_history,
 4789
 4790                            lang_server.clone(),
 4791                            cx,
 4792                        )
 4793                        .await;
 4794                    }
 4795
 4796                if let Some(command) = action.lsp_action.command() {
 4797                    let server_capabilities = lang_server.capabilities();
 4798                    let available_commands = server_capabilities
 4799                        .execute_command_provider
 4800                        .as_ref()
 4801                        .map(|options| options.commands.as_slice())
 4802                        .unwrap_or_default();
 4803                    if available_commands.contains(&command.command) {
 4804                        this.update(cx, |this, _| {
 4805                            this.as_local_mut()
 4806                                .unwrap()
 4807                                .last_workspace_edits_by_language_server
 4808                                .remove(&lang_server.server_id());
 4809                        })?;
 4810
 4811                        let _result = lang_server
 4812                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4813                                command: command.command.clone(),
 4814                                arguments: command.arguments.clone().unwrap_or_default(),
 4815                                ..lsp::ExecuteCommandParams::default()
 4816                            })
 4817                            .await.into_response()
 4818                            .context("execute command")?;
 4819
 4820                        return this.update(cx, |this, _| {
 4821                            this.as_local_mut()
 4822                                .unwrap()
 4823                                .last_workspace_edits_by_language_server
 4824                                .remove(&lang_server.server_id())
 4825                                .unwrap_or_default()
 4826                        });
 4827                    } else {
 4828                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4829                    }
 4830                }
 4831
 4832                Ok(ProjectTransaction::default())
 4833            })
 4834        } else {
 4835            Task::ready(Err(anyhow!("no upstream client and not local")))
 4836        }
 4837    }
 4838
 4839    pub fn apply_code_action_kind(
 4840        &mut self,
 4841        buffers: HashSet<Entity<Buffer>>,
 4842        kind: CodeActionKind,
 4843        push_to_history: bool,
 4844        cx: &mut Context<Self>,
 4845    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4846        if self.as_local().is_some() {
 4847            cx.spawn(async move |lsp_store, cx| {
 4848                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4849                let result = LocalLspStore::execute_code_action_kind_locally(
 4850                    lsp_store.clone(),
 4851                    buffers,
 4852                    kind,
 4853                    push_to_history,
 4854                    cx,
 4855                )
 4856                .await;
 4857                lsp_store.update(cx, |lsp_store, _| {
 4858                    lsp_store.update_last_formatting_failure(&result);
 4859                })?;
 4860                result
 4861            })
 4862        } else if let Some((client, project_id)) = self.upstream_client() {
 4863            let buffer_store = self.buffer_store();
 4864            cx.spawn(async move |lsp_store, cx| {
 4865                let result = client
 4866                    .request(proto::ApplyCodeActionKind {
 4867                        project_id,
 4868                        kind: kind.as_str().to_owned(),
 4869                        buffer_ids: buffers
 4870                            .iter()
 4871                            .map(|buffer| {
 4872                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4873                            })
 4874                            .collect::<Result<_>>()?,
 4875                    })
 4876                    .await
 4877                    .and_then(|result| result.transaction.context("missing transaction"));
 4878                lsp_store.update(cx, |lsp_store, _| {
 4879                    lsp_store.update_last_formatting_failure(&result);
 4880                })?;
 4881
 4882                let transaction_response = result?;
 4883                buffer_store
 4884                    .update(cx, |buffer_store, cx| {
 4885                        buffer_store.deserialize_project_transaction(
 4886                            transaction_response,
 4887                            push_to_history,
 4888                            cx,
 4889                        )
 4890                    })?
 4891                    .await
 4892            })
 4893        } else {
 4894            Task::ready(Ok(ProjectTransaction::default()))
 4895        }
 4896    }
 4897
 4898    pub fn resolve_inlay_hint(
 4899        &self,
 4900        mut hint: InlayHint,
 4901        buffer: Entity<Buffer>,
 4902        server_id: LanguageServerId,
 4903        cx: &mut Context<Self>,
 4904    ) -> Task<anyhow::Result<InlayHint>> {
 4905        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4906            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4907            {
 4908                hint.resolve_state = ResolveState::Resolved;
 4909                return Task::ready(Ok(hint));
 4910            }
 4911            let request = proto::ResolveInlayHint {
 4912                project_id,
 4913                buffer_id: buffer.read(cx).remote_id().into(),
 4914                language_server_id: server_id.0 as u64,
 4915                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4916            };
 4917            cx.background_spawn(async move {
 4918                let response = upstream_client
 4919                    .request(request)
 4920                    .await
 4921                    .context("inlay hints proto request")?;
 4922                match response.hint {
 4923                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4924                        .context("inlay hints proto resolve response conversion"),
 4925                    None => Ok(hint),
 4926                }
 4927            })
 4928        } else {
 4929            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4930                self.language_server_for_local_buffer(buffer, server_id, cx)
 4931                    .map(|(_, server)| server.clone())
 4932            }) else {
 4933                return Task::ready(Ok(hint));
 4934            };
 4935            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4936                return Task::ready(Ok(hint));
 4937            }
 4938            let buffer_snapshot = buffer.read(cx).snapshot();
 4939            cx.spawn(async move |_, cx| {
 4940                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4941                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4942                );
 4943                let resolved_hint = resolve_task
 4944                    .await
 4945                    .into_response()
 4946                    .context("inlay hint resolve LSP request")?;
 4947                let resolved_hint = InlayHints::lsp_to_project_hint(
 4948                    resolved_hint,
 4949                    &buffer,
 4950                    server_id,
 4951                    ResolveState::Resolved,
 4952                    false,
 4953                    cx,
 4954                )
 4955                .await?;
 4956                Ok(resolved_hint)
 4957            })
 4958        }
 4959    }
 4960
 4961    pub fn resolve_color_presentation(
 4962        &mut self,
 4963        mut color: DocumentColor,
 4964        buffer: Entity<Buffer>,
 4965        server_id: LanguageServerId,
 4966        cx: &mut Context<Self>,
 4967    ) -> Task<Result<DocumentColor>> {
 4968        if color.resolved {
 4969            return Task::ready(Ok(color));
 4970        }
 4971
 4972        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4973            let start = color.lsp_range.start;
 4974            let end = color.lsp_range.end;
 4975            let request = proto::GetColorPresentation {
 4976                project_id,
 4977                server_id: server_id.to_proto(),
 4978                buffer_id: buffer.read(cx).remote_id().into(),
 4979                color: Some(proto::ColorInformation {
 4980                    red: color.color.red,
 4981                    green: color.color.green,
 4982                    blue: color.color.blue,
 4983                    alpha: color.color.alpha,
 4984                    lsp_range_start: Some(proto::PointUtf16 {
 4985                        row: start.line,
 4986                        column: start.character,
 4987                    }),
 4988                    lsp_range_end: Some(proto::PointUtf16 {
 4989                        row: end.line,
 4990                        column: end.character,
 4991                    }),
 4992                }),
 4993            };
 4994            cx.background_spawn(async move {
 4995                let response = upstream_client
 4996                    .request(request)
 4997                    .await
 4998                    .context("color presentation proto request")?;
 4999                color.resolved = true;
 5000                color.color_presentations = response
 5001                    .presentations
 5002                    .into_iter()
 5003                    .map(|presentation| ColorPresentation {
 5004                        label: SharedString::from(presentation.label),
 5005                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5006                        additional_text_edits: presentation
 5007                            .additional_text_edits
 5008                            .into_iter()
 5009                            .filter_map(deserialize_lsp_edit)
 5010                            .collect(),
 5011                    })
 5012                    .collect();
 5013                Ok(color)
 5014            })
 5015        } else {
 5016            let path = match buffer
 5017                .update(cx, |buffer, cx| {
 5018                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5019                })
 5020                .context("buffer with the missing path")
 5021            {
 5022                Ok(path) => path,
 5023                Err(e) => return Task::ready(Err(e)),
 5024            };
 5025            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5026                self.language_server_for_local_buffer(buffer, server_id, cx)
 5027                    .map(|(_, server)| server.clone())
 5028            }) else {
 5029                return Task::ready(Ok(color));
 5030            };
 5031            cx.background_spawn(async move {
 5032                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5033                    lsp::ColorPresentationParams {
 5034                        text_document: make_text_document_identifier(&path)?,
 5035                        color: color.color,
 5036                        range: color.lsp_range,
 5037                        work_done_progress_params: Default::default(),
 5038                        partial_result_params: Default::default(),
 5039                    },
 5040                );
 5041                color.color_presentations = resolve_task
 5042                    .await
 5043                    .into_response()
 5044                    .context("color presentation resolve LSP request")?
 5045                    .into_iter()
 5046                    .map(|presentation| ColorPresentation {
 5047                        label: SharedString::from(presentation.label),
 5048                        text_edit: presentation.text_edit,
 5049                        additional_text_edits: presentation
 5050                            .additional_text_edits
 5051                            .unwrap_or_default(),
 5052                    })
 5053                    .collect();
 5054                color.resolved = true;
 5055                Ok(color)
 5056            })
 5057        }
 5058    }
 5059
 5060    pub(crate) fn linked_edits(
 5061        &mut self,
 5062        buffer: &Entity<Buffer>,
 5063        position: Anchor,
 5064        cx: &mut Context<Self>,
 5065    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5066        let snapshot = buffer.read(cx).snapshot();
 5067        let scope = snapshot.language_scope_at(position);
 5068        let Some(server_id) = self
 5069            .as_local()
 5070            .and_then(|local| {
 5071                buffer.update(cx, |buffer, cx| {
 5072                    local
 5073                        .language_servers_for_buffer(buffer, cx)
 5074                        .filter(|(_, server)| {
 5075                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5076                        })
 5077                        .filter(|(adapter, _)| {
 5078                            scope
 5079                                .as_ref()
 5080                                .map(|scope| scope.language_allowed(&adapter.name))
 5081                                .unwrap_or(true)
 5082                        })
 5083                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5084                        .next()
 5085                })
 5086            })
 5087            .or_else(|| {
 5088                self.upstream_client()
 5089                    .is_some()
 5090                    .then_some(LanguageServerToQuery::FirstCapable)
 5091            })
 5092            .filter(|_| {
 5093                maybe!({
 5094                    let language = buffer.read(cx).language_at(position)?;
 5095                    Some(
 5096                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5097                            .linked_edits,
 5098                    )
 5099                }) == Some(true)
 5100            })
 5101        else {
 5102            return Task::ready(Ok(Vec::new()));
 5103        };
 5104
 5105        self.request_lsp(
 5106            buffer.clone(),
 5107            server_id,
 5108            LinkedEditingRange { position },
 5109            cx,
 5110        )
 5111    }
 5112
 5113    fn apply_on_type_formatting(
 5114        &mut self,
 5115        buffer: Entity<Buffer>,
 5116        position: Anchor,
 5117        trigger: String,
 5118        cx: &mut Context<Self>,
 5119    ) -> Task<Result<Option<Transaction>>> {
 5120        if let Some((client, project_id)) = self.upstream_client() {
 5121            if !self.check_if_capable_for_proto_request(
 5122                &buffer,
 5123                |capabilities| {
 5124                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5125                },
 5126                cx,
 5127            ) {
 5128                return Task::ready(Ok(None));
 5129            }
 5130            let request = proto::OnTypeFormatting {
 5131                project_id,
 5132                buffer_id: buffer.read(cx).remote_id().into(),
 5133                position: Some(serialize_anchor(&position)),
 5134                trigger,
 5135                version: serialize_version(&buffer.read(cx).version()),
 5136            };
 5137            cx.background_spawn(async move {
 5138                client
 5139                    .request(request)
 5140                    .await?
 5141                    .transaction
 5142                    .map(language::proto::deserialize_transaction)
 5143                    .transpose()
 5144            })
 5145        } else if let Some(local) = self.as_local_mut() {
 5146            let buffer_id = buffer.read(cx).remote_id();
 5147            local.buffers_being_formatted.insert(buffer_id);
 5148            cx.spawn(async move |this, cx| {
 5149                let _cleanup = defer({
 5150                    let this = this.clone();
 5151                    let mut cx = cx.clone();
 5152                    move || {
 5153                        this.update(&mut cx, |this, _| {
 5154                            if let Some(local) = this.as_local_mut() {
 5155                                local.buffers_being_formatted.remove(&buffer_id);
 5156                            }
 5157                        })
 5158                        .ok();
 5159                    }
 5160                });
 5161
 5162                buffer
 5163                    .update(cx, |buffer, _| {
 5164                        buffer.wait_for_edits(Some(position.timestamp))
 5165                    })?
 5166                    .await?;
 5167                this.update(cx, |this, cx| {
 5168                    let position = position.to_point_utf16(buffer.read(cx));
 5169                    this.on_type_format(buffer, position, trigger, false, cx)
 5170                })?
 5171                .await
 5172            })
 5173        } else {
 5174            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5175        }
 5176    }
 5177
 5178    pub fn on_type_format<T: ToPointUtf16>(
 5179        &mut self,
 5180        buffer: Entity<Buffer>,
 5181        position: T,
 5182        trigger: String,
 5183        push_to_history: bool,
 5184        cx: &mut Context<Self>,
 5185    ) -> Task<Result<Option<Transaction>>> {
 5186        let position = position.to_point_utf16(buffer.read(cx));
 5187        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5188    }
 5189
 5190    fn on_type_format_impl(
 5191        &mut self,
 5192        buffer: Entity<Buffer>,
 5193        position: PointUtf16,
 5194        trigger: String,
 5195        push_to_history: bool,
 5196        cx: &mut Context<Self>,
 5197    ) -> Task<Result<Option<Transaction>>> {
 5198        let options = buffer.update(cx, |buffer, cx| {
 5199            lsp_command::lsp_formatting_options(
 5200                language_settings(
 5201                    buffer.language_at(position).map(|l| l.name()),
 5202                    buffer.file(),
 5203                    cx,
 5204                )
 5205                .as_ref(),
 5206            )
 5207        });
 5208
 5209        cx.spawn(async move |this, cx| {
 5210            if let Some(waiter) =
 5211                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5212            {
 5213                waiter.await?;
 5214            }
 5215            cx.update(|cx| {
 5216                this.update(cx, |this, cx| {
 5217                    this.request_lsp(
 5218                        buffer.clone(),
 5219                        LanguageServerToQuery::FirstCapable,
 5220                        OnTypeFormatting {
 5221                            position,
 5222                            trigger,
 5223                            options,
 5224                            push_to_history,
 5225                        },
 5226                        cx,
 5227                    )
 5228                })
 5229            })??
 5230            .await
 5231        })
 5232    }
 5233
 5234    pub fn definitions(
 5235        &mut self,
 5236        buffer_handle: &Entity<Buffer>,
 5237        position: PointUtf16,
 5238        cx: &mut Context<Self>,
 5239    ) -> Task<Result<Vec<LocationLink>>> {
 5240        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5241            let request = GetDefinitions { position };
 5242            if !self.is_capable_for_proto_request(buffer_handle, &request, cx) {
 5243                return Task::ready(Ok(Vec::new()));
 5244            }
 5245            let request_task = upstream_client.request(proto::MultiLspQuery {
 5246                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5247                version: serialize_version(&buffer_handle.read(cx).version()),
 5248                project_id,
 5249                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5250                    proto::AllLanguageServers {},
 5251                )),
 5252                request: Some(proto::multi_lsp_query::Request::GetDefinition(
 5253                    request.to_proto(project_id, buffer_handle.read(cx)),
 5254                )),
 5255            });
 5256            let buffer = buffer_handle.clone();
 5257            cx.spawn(async move |weak_project, cx| {
 5258                let Some(project) = weak_project.upgrade() else {
 5259                    return Ok(Vec::new());
 5260                };
 5261                let responses = request_task.await?.responses;
 5262                let actions = join_all(
 5263                    responses
 5264                        .into_iter()
 5265                        .filter_map(|lsp_response| match lsp_response.response? {
 5266                            proto::lsp_response::Response::GetDefinitionResponse(response) => {
 5267                                Some(response)
 5268                            }
 5269                            unexpected => {
 5270                                debug_panic!("Unexpected response: {unexpected:?}");
 5271                                None
 5272                            }
 5273                        })
 5274                        .map(|definitions_response| {
 5275                            GetDefinitions { position }.response_from_proto(
 5276                                definitions_response,
 5277                                project.clone(),
 5278                                buffer.clone(),
 5279                                cx.clone(),
 5280                            )
 5281                        }),
 5282                )
 5283                .await;
 5284
 5285                Ok(actions
 5286                    .into_iter()
 5287                    .collect::<Result<Vec<Vec<_>>>>()?
 5288                    .into_iter()
 5289                    .flatten()
 5290                    .dedup()
 5291                    .collect())
 5292            })
 5293        } else {
 5294            let definitions_task = self.request_multiple_lsp_locally(
 5295                buffer_handle,
 5296                Some(position),
 5297                GetDefinitions { position },
 5298                cx,
 5299            );
 5300            cx.background_spawn(async move {
 5301                Ok(definitions_task
 5302                    .await
 5303                    .into_iter()
 5304                    .flat_map(|(_, definitions)| definitions)
 5305                    .dedup()
 5306                    .collect())
 5307            })
 5308        }
 5309    }
 5310
 5311    pub fn declarations(
 5312        &mut self,
 5313        buffer_handle: &Entity<Buffer>,
 5314        position: PointUtf16,
 5315        cx: &mut Context<Self>,
 5316    ) -> Task<Result<Vec<LocationLink>>> {
 5317        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5318            let request = GetDeclarations { position };
 5319            if !self.is_capable_for_proto_request(buffer_handle, &request, cx) {
 5320                return Task::ready(Ok(Vec::new()));
 5321            }
 5322            let request_task = upstream_client.request(proto::MultiLspQuery {
 5323                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5324                version: serialize_version(&buffer_handle.read(cx).version()),
 5325                project_id,
 5326                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5327                    proto::AllLanguageServers {},
 5328                )),
 5329                request: Some(proto::multi_lsp_query::Request::GetDeclaration(
 5330                    request.to_proto(project_id, buffer_handle.read(cx)),
 5331                )),
 5332            });
 5333            let buffer = buffer_handle.clone();
 5334            cx.spawn(async move |weak_project, cx| {
 5335                let Some(project) = weak_project.upgrade() else {
 5336                    return Ok(Vec::new());
 5337                };
 5338                let responses = request_task.await?.responses;
 5339                let actions = join_all(
 5340                    responses
 5341                        .into_iter()
 5342                        .filter_map(|lsp_response| match lsp_response.response? {
 5343                            proto::lsp_response::Response::GetDeclarationResponse(response) => {
 5344                                Some(response)
 5345                            }
 5346                            unexpected => {
 5347                                debug_panic!("Unexpected response: {unexpected:?}");
 5348                                None
 5349                            }
 5350                        })
 5351                        .map(|declarations_response| {
 5352                            GetDeclarations { position }.response_from_proto(
 5353                                declarations_response,
 5354                                project.clone(),
 5355                                buffer.clone(),
 5356                                cx.clone(),
 5357                            )
 5358                        }),
 5359                )
 5360                .await;
 5361
 5362                Ok(actions
 5363                    .into_iter()
 5364                    .collect::<Result<Vec<Vec<_>>>>()?
 5365                    .into_iter()
 5366                    .flatten()
 5367                    .dedup()
 5368                    .collect())
 5369            })
 5370        } else {
 5371            let declarations_task = self.request_multiple_lsp_locally(
 5372                buffer_handle,
 5373                Some(position),
 5374                GetDeclarations { position },
 5375                cx,
 5376            );
 5377            cx.background_spawn(async move {
 5378                Ok(declarations_task
 5379                    .await
 5380                    .into_iter()
 5381                    .flat_map(|(_, declarations)| declarations)
 5382                    .dedup()
 5383                    .collect())
 5384            })
 5385        }
 5386    }
 5387
 5388    pub fn type_definitions(
 5389        &mut self,
 5390        buffer: &Entity<Buffer>,
 5391        position: PointUtf16,
 5392        cx: &mut Context<Self>,
 5393    ) -> Task<Result<Vec<LocationLink>>> {
 5394        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5395            let request = GetTypeDefinitions { position };
 5396            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5397                return Task::ready(Ok(Vec::new()));
 5398            }
 5399            let request_task = upstream_client.request(proto::MultiLspQuery {
 5400                buffer_id: buffer.read(cx).remote_id().into(),
 5401                version: serialize_version(&buffer.read(cx).version()),
 5402                project_id,
 5403                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5404                    proto::AllLanguageServers {},
 5405                )),
 5406                request: Some(proto::multi_lsp_query::Request::GetTypeDefinition(
 5407                    request.to_proto(project_id, buffer.read(cx)),
 5408                )),
 5409            });
 5410            let buffer = buffer.clone();
 5411            cx.spawn(async move |weak_project, cx| {
 5412                let Some(project) = weak_project.upgrade() else {
 5413                    return Ok(Vec::new());
 5414                };
 5415                let responses = request_task.await?.responses;
 5416                let actions = join_all(
 5417                    responses
 5418                        .into_iter()
 5419                        .filter_map(|lsp_response| match lsp_response.response? {
 5420                            proto::lsp_response::Response::GetTypeDefinitionResponse(response) => {
 5421                                Some(response)
 5422                            }
 5423                            unexpected => {
 5424                                debug_panic!("Unexpected response: {unexpected:?}");
 5425                                None
 5426                            }
 5427                        })
 5428                        .map(|type_definitions_response| {
 5429                            GetTypeDefinitions { position }.response_from_proto(
 5430                                type_definitions_response,
 5431                                project.clone(),
 5432                                buffer.clone(),
 5433                                cx.clone(),
 5434                            )
 5435                        }),
 5436                )
 5437                .await;
 5438
 5439                Ok(actions
 5440                    .into_iter()
 5441                    .collect::<Result<Vec<Vec<_>>>>()?
 5442                    .into_iter()
 5443                    .flatten()
 5444                    .dedup()
 5445                    .collect())
 5446            })
 5447        } else {
 5448            let type_definitions_task = self.request_multiple_lsp_locally(
 5449                buffer,
 5450                Some(position),
 5451                GetTypeDefinitions { position },
 5452                cx,
 5453            );
 5454            cx.background_spawn(async move {
 5455                Ok(type_definitions_task
 5456                    .await
 5457                    .into_iter()
 5458                    .flat_map(|(_, type_definitions)| type_definitions)
 5459                    .dedup()
 5460                    .collect())
 5461            })
 5462        }
 5463    }
 5464
 5465    pub fn implementations(
 5466        &mut self,
 5467        buffer: &Entity<Buffer>,
 5468        position: PointUtf16,
 5469        cx: &mut Context<Self>,
 5470    ) -> Task<Result<Vec<LocationLink>>> {
 5471        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5472            let request = GetImplementations { position };
 5473            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5474                return Task::ready(Ok(Vec::new()));
 5475            }
 5476            let request_task = upstream_client.request(proto::MultiLspQuery {
 5477                buffer_id: buffer.read(cx).remote_id().into(),
 5478                version: serialize_version(&buffer.read(cx).version()),
 5479                project_id,
 5480                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5481                    proto::AllLanguageServers {},
 5482                )),
 5483                request: Some(proto::multi_lsp_query::Request::GetImplementation(
 5484                    request.to_proto(project_id, buffer.read(cx)),
 5485                )),
 5486            });
 5487            let buffer = buffer.clone();
 5488            cx.spawn(async move |weak_project, cx| {
 5489                let Some(project) = weak_project.upgrade() else {
 5490                    return Ok(Vec::new());
 5491                };
 5492                let responses = request_task.await?.responses;
 5493                let actions = join_all(
 5494                    responses
 5495                        .into_iter()
 5496                        .filter_map(|lsp_response| match lsp_response.response? {
 5497                            proto::lsp_response::Response::GetImplementationResponse(response) => {
 5498                                Some(response)
 5499                            }
 5500                            unexpected => {
 5501                                debug_panic!("Unexpected response: {unexpected:?}");
 5502                                None
 5503                            }
 5504                        })
 5505                        .map(|implementations_response| {
 5506                            GetImplementations { position }.response_from_proto(
 5507                                implementations_response,
 5508                                project.clone(),
 5509                                buffer.clone(),
 5510                                cx.clone(),
 5511                            )
 5512                        }),
 5513                )
 5514                .await;
 5515
 5516                Ok(actions
 5517                    .into_iter()
 5518                    .collect::<Result<Vec<Vec<_>>>>()?
 5519                    .into_iter()
 5520                    .flatten()
 5521                    .dedup()
 5522                    .collect())
 5523            })
 5524        } else {
 5525            let implementations_task = self.request_multiple_lsp_locally(
 5526                buffer,
 5527                Some(position),
 5528                GetImplementations { position },
 5529                cx,
 5530            );
 5531            cx.background_spawn(async move {
 5532                Ok(implementations_task
 5533                    .await
 5534                    .into_iter()
 5535                    .flat_map(|(_, implementations)| implementations)
 5536                    .dedup()
 5537                    .collect())
 5538            })
 5539        }
 5540    }
 5541
 5542    pub fn references(
 5543        &mut self,
 5544        buffer: &Entity<Buffer>,
 5545        position: PointUtf16,
 5546        cx: &mut Context<Self>,
 5547    ) -> Task<Result<Vec<Location>>> {
 5548        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5549            let request = GetReferences { position };
 5550            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5551                return Task::ready(Ok(Vec::new()));
 5552            }
 5553            let request_task = upstream_client.request(proto::MultiLspQuery {
 5554                buffer_id: buffer.read(cx).remote_id().into(),
 5555                version: serialize_version(&buffer.read(cx).version()),
 5556                project_id,
 5557                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5558                    proto::AllLanguageServers {},
 5559                )),
 5560                request: Some(proto::multi_lsp_query::Request::GetReferences(
 5561                    request.to_proto(project_id, buffer.read(cx)),
 5562                )),
 5563            });
 5564            let buffer = buffer.clone();
 5565            cx.spawn(async move |weak_project, cx| {
 5566                let Some(project) = weak_project.upgrade() else {
 5567                    return Ok(Vec::new());
 5568                };
 5569                let responses = request_task.await?.responses;
 5570                let actions = join_all(
 5571                    responses
 5572                        .into_iter()
 5573                        .filter_map(|lsp_response| match lsp_response.response? {
 5574                            proto::lsp_response::Response::GetReferencesResponse(response) => {
 5575                                Some(response)
 5576                            }
 5577                            unexpected => {
 5578                                debug_panic!("Unexpected response: {unexpected:?}");
 5579                                None
 5580                            }
 5581                        })
 5582                        .map(|references_response| {
 5583                            GetReferences { position }.response_from_proto(
 5584                                references_response,
 5585                                project.clone(),
 5586                                buffer.clone(),
 5587                                cx.clone(),
 5588                            )
 5589                        }),
 5590                )
 5591                .await;
 5592
 5593                Ok(actions
 5594                    .into_iter()
 5595                    .collect::<Result<Vec<Vec<_>>>>()?
 5596                    .into_iter()
 5597                    .flatten()
 5598                    .dedup()
 5599                    .collect())
 5600            })
 5601        } else {
 5602            let references_task = self.request_multiple_lsp_locally(
 5603                buffer,
 5604                Some(position),
 5605                GetReferences { position },
 5606                cx,
 5607            );
 5608            cx.background_spawn(async move {
 5609                Ok(references_task
 5610                    .await
 5611                    .into_iter()
 5612                    .flat_map(|(_, references)| references)
 5613                    .dedup()
 5614                    .collect())
 5615            })
 5616        }
 5617    }
 5618
 5619    pub fn code_actions(
 5620        &mut self,
 5621        buffer: &Entity<Buffer>,
 5622        range: Range<Anchor>,
 5623        kinds: Option<Vec<CodeActionKind>>,
 5624        cx: &mut Context<Self>,
 5625    ) -> Task<Result<Vec<CodeAction>>> {
 5626        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5627            let request = GetCodeActions {
 5628                range: range.clone(),
 5629                kinds: kinds.clone(),
 5630            };
 5631            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5632                return Task::ready(Ok(Vec::new()));
 5633            }
 5634            let request_task = upstream_client.request(proto::MultiLspQuery {
 5635                buffer_id: buffer.read(cx).remote_id().into(),
 5636                version: serialize_version(&buffer.read(cx).version()),
 5637                project_id,
 5638                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5639                    proto::AllLanguageServers {},
 5640                )),
 5641                request: Some(proto::multi_lsp_query::Request::GetCodeActions(
 5642                    request.to_proto(project_id, buffer.read(cx)),
 5643                )),
 5644            });
 5645            let buffer = buffer.clone();
 5646            cx.spawn(async move |weak_project, cx| {
 5647                let Some(project) = weak_project.upgrade() else {
 5648                    return Ok(Vec::new());
 5649                };
 5650                let responses = request_task.await?.responses;
 5651                let actions = join_all(
 5652                    responses
 5653                        .into_iter()
 5654                        .filter_map(|lsp_response| match lsp_response.response? {
 5655                            proto::lsp_response::Response::GetCodeActionsResponse(response) => {
 5656                                Some(response)
 5657                            }
 5658                            unexpected => {
 5659                                debug_panic!("Unexpected response: {unexpected:?}");
 5660                                None
 5661                            }
 5662                        })
 5663                        .map(|code_actions_response| {
 5664                            GetCodeActions {
 5665                                range: range.clone(),
 5666                                kinds: kinds.clone(),
 5667                            }
 5668                            .response_from_proto(
 5669                                code_actions_response,
 5670                                project.clone(),
 5671                                buffer.clone(),
 5672                                cx.clone(),
 5673                            )
 5674                        }),
 5675                )
 5676                .await;
 5677
 5678                Ok(actions
 5679                    .into_iter()
 5680                    .collect::<Result<Vec<Vec<_>>>>()?
 5681                    .into_iter()
 5682                    .flatten()
 5683                    .collect())
 5684            })
 5685        } else {
 5686            let all_actions_task = self.request_multiple_lsp_locally(
 5687                buffer,
 5688                Some(range.start),
 5689                GetCodeActions { range, kinds },
 5690                cx,
 5691            );
 5692            cx.background_spawn(async move {
 5693                Ok(all_actions_task
 5694                    .await
 5695                    .into_iter()
 5696                    .flat_map(|(_, actions)| actions)
 5697                    .collect())
 5698            })
 5699        }
 5700    }
 5701
 5702    pub fn code_lens_actions(
 5703        &mut self,
 5704        buffer: &Entity<Buffer>,
 5705        cx: &mut Context<Self>,
 5706    ) -> CodeLensTask {
 5707        let version_queried_for = buffer.read(cx).version();
 5708        let buffer_id = buffer.read(cx).remote_id();
 5709
 5710        if let Some(cached_data) = self.lsp_code_lens.get(&buffer_id)
 5711            && !version_queried_for.changed_since(&cached_data.lens_for_version)
 5712        {
 5713            let has_different_servers = self.as_local().is_some_and(|local| {
 5714                local
 5715                    .buffers_opened_in_servers
 5716                    .get(&buffer_id)
 5717                    .cloned()
 5718                    .unwrap_or_default()
 5719                    != cached_data.lens.keys().copied().collect()
 5720            });
 5721            if !has_different_servers {
 5722                return Task::ready(Ok(cached_data.lens.values().flatten().cloned().collect()))
 5723                    .shared();
 5724            }
 5725        }
 5726
 5727        let lsp_data = self.lsp_code_lens.entry(buffer_id).or_default();
 5728        if let Some((updating_for, running_update)) = &lsp_data.update
 5729            && !version_queried_for.changed_since(updating_for)
 5730        {
 5731            return running_update.clone();
 5732        }
 5733        let buffer = buffer.clone();
 5734        let query_version_queried_for = version_queried_for.clone();
 5735        let new_task = cx
 5736            .spawn(async move |lsp_store, cx| {
 5737                cx.background_executor()
 5738                    .timer(Duration::from_millis(30))
 5739                    .await;
 5740                let fetched_lens = lsp_store
 5741                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5742                    .map_err(Arc::new)?
 5743                    .await
 5744                    .context("fetching code lens")
 5745                    .map_err(Arc::new);
 5746                let fetched_lens = match fetched_lens {
 5747                    Ok(fetched_lens) => fetched_lens,
 5748                    Err(e) => {
 5749                        lsp_store
 5750                            .update(cx, |lsp_store, _| {
 5751                                lsp_store.lsp_code_lens.entry(buffer_id).or_default().update = None;
 5752                            })
 5753                            .ok();
 5754                        return Err(e);
 5755                    }
 5756                };
 5757
 5758                lsp_store
 5759                    .update(cx, |lsp_store, _| {
 5760                        let lsp_data = lsp_store.lsp_code_lens.entry(buffer_id).or_default();
 5761                        if lsp_data.lens_for_version == query_version_queried_for {
 5762                            lsp_data.lens.extend(fetched_lens.clone());
 5763                        } else if !lsp_data
 5764                            .lens_for_version
 5765                            .changed_since(&query_version_queried_for)
 5766                        {
 5767                            lsp_data.lens_for_version = query_version_queried_for;
 5768                            lsp_data.lens = fetched_lens.clone();
 5769                        }
 5770                        lsp_data.update = None;
 5771                        lsp_data.lens.values().flatten().cloned().collect()
 5772                    })
 5773                    .map_err(Arc::new)
 5774            })
 5775            .shared();
 5776        lsp_data.update = Some((version_queried_for, new_task.clone()));
 5777        new_task
 5778    }
 5779
 5780    fn fetch_code_lens(
 5781        &mut self,
 5782        buffer: &Entity<Buffer>,
 5783        cx: &mut Context<Self>,
 5784    ) -> Task<Result<HashMap<LanguageServerId, Vec<CodeAction>>>> {
 5785        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5786            let request = GetCodeLens;
 5787            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5788                return Task::ready(Ok(HashMap::default()));
 5789            }
 5790            let request_task = upstream_client.request(proto::MultiLspQuery {
 5791                buffer_id: buffer.read(cx).remote_id().into(),
 5792                version: serialize_version(&buffer.read(cx).version()),
 5793                project_id,
 5794                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5795                    proto::AllLanguageServers {},
 5796                )),
 5797                request: Some(proto::multi_lsp_query::Request::GetCodeLens(
 5798                    request.to_proto(project_id, buffer.read(cx)),
 5799                )),
 5800            });
 5801            let buffer = buffer.clone();
 5802            cx.spawn(async move |weak_lsp_store, cx| {
 5803                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5804                    return Ok(HashMap::default());
 5805                };
 5806                let responses = request_task.await?.responses;
 5807                let code_lens_actions = join_all(
 5808                    responses
 5809                        .into_iter()
 5810                        .filter_map(|lsp_response| {
 5811                            let response = match lsp_response.response? {
 5812                                proto::lsp_response::Response::GetCodeLensResponse(response) => {
 5813                                    Some(response)
 5814                                }
 5815                                unexpected => {
 5816                                    debug_panic!("Unexpected response: {unexpected:?}");
 5817                                    None
 5818                                }
 5819                            }?;
 5820                            let server_id = LanguageServerId::from_proto(lsp_response.server_id);
 5821                            Some((server_id, response))
 5822                        })
 5823                        .map(|(server_id, code_lens_response)| {
 5824                            let lsp_store = lsp_store.clone();
 5825                            let buffer = buffer.clone();
 5826                            let cx = cx.clone();
 5827                            async move {
 5828                                (
 5829                                    server_id,
 5830                                    GetCodeLens
 5831                                        .response_from_proto(
 5832                                            code_lens_response,
 5833                                            lsp_store,
 5834                                            buffer,
 5835                                            cx,
 5836                                        )
 5837                                        .await,
 5838                                )
 5839                            }
 5840                        }),
 5841                )
 5842                .await;
 5843
 5844                let mut has_errors = false;
 5845                let code_lens_actions = code_lens_actions
 5846                    .into_iter()
 5847                    .filter_map(|(server_id, code_lens)| match code_lens {
 5848                        Ok(code_lens) => Some((server_id, code_lens)),
 5849                        Err(e) => {
 5850                            has_errors = true;
 5851                            log::error!("{e:#}");
 5852                            None
 5853                        }
 5854                    })
 5855                    .collect::<HashMap<_, _>>();
 5856                anyhow::ensure!(
 5857                    !has_errors || !code_lens_actions.is_empty(),
 5858                    "Failed to fetch code lens"
 5859                );
 5860                Ok(code_lens_actions)
 5861            })
 5862        } else {
 5863            let code_lens_actions_task =
 5864                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5865            cx.background_spawn(
 5866                async move { Ok(code_lens_actions_task.await.into_iter().collect()) },
 5867            )
 5868        }
 5869    }
 5870
 5871    #[inline(never)]
 5872    pub fn completions(
 5873        &self,
 5874        buffer: &Entity<Buffer>,
 5875        position: PointUtf16,
 5876        context: CompletionContext,
 5877        cx: &mut Context<Self>,
 5878    ) -> Task<Result<Vec<CompletionResponse>>> {
 5879        let language_registry = self.languages.clone();
 5880
 5881        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5882            let request = GetCompletions { position, context };
 5883            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5884                return Task::ready(Ok(Vec::new()));
 5885            }
 5886            let task = self.send_lsp_proto_request(
 5887                buffer.clone(),
 5888                upstream_client,
 5889                project_id,
 5890                request,
 5891                cx,
 5892            );
 5893            let language = buffer.read(cx).language().cloned();
 5894
 5895            // In the future, we should provide project guests with the names of LSP adapters,
 5896            // so that they can use the correct LSP adapter when computing labels. For now,
 5897            // guests just use the first LSP adapter associated with the buffer's language.
 5898            let lsp_adapter = language.as_ref().and_then(|language| {
 5899                language_registry
 5900                    .lsp_adapters(&language.name())
 5901                    .first()
 5902                    .cloned()
 5903            });
 5904
 5905            cx.foreground_executor().spawn(async move {
 5906                let completion_response = task.await?;
 5907                let completions = populate_labels_for_completions(
 5908                    completion_response.completions,
 5909                    language,
 5910                    lsp_adapter,
 5911                )
 5912                .await;
 5913                Ok(vec![CompletionResponse {
 5914                    completions,
 5915                    is_incomplete: completion_response.is_incomplete,
 5916                }])
 5917            })
 5918        } else if let Some(local) = self.as_local() {
 5919            let snapshot = buffer.read(cx).snapshot();
 5920            let offset = position.to_offset(&snapshot);
 5921            let scope = snapshot.language_scope_at(offset);
 5922            let language = snapshot.language().cloned();
 5923            let completion_settings = language_settings(
 5924                language.as_ref().map(|language| language.name()),
 5925                buffer.read(cx).file(),
 5926                cx,
 5927            )
 5928            .completions;
 5929            if !completion_settings.lsp {
 5930                return Task::ready(Ok(Vec::new()));
 5931            }
 5932
 5933            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5934                local
 5935                    .language_servers_for_buffer(buffer, cx)
 5936                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5937                    .filter(|(adapter, _)| {
 5938                        scope
 5939                            .as_ref()
 5940                            .map(|scope| scope.language_allowed(&adapter.name))
 5941                            .unwrap_or(true)
 5942                    })
 5943                    .map(|(_, server)| server.server_id())
 5944                    .collect()
 5945            });
 5946
 5947            let buffer = buffer.clone();
 5948            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5949            let lsp_timeout = if lsp_timeout > 0 {
 5950                Some(Duration::from_millis(lsp_timeout))
 5951            } else {
 5952                None
 5953            };
 5954            cx.spawn(async move |this,  cx| {
 5955                let mut tasks = Vec::with_capacity(server_ids.len());
 5956                this.update(cx, |lsp_store, cx| {
 5957                    for server_id in server_ids {
 5958                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5959                        let lsp_timeout = lsp_timeout
 5960                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5961                        let mut timeout = cx.background_spawn(async move {
 5962                            match lsp_timeout {
 5963                                Some(lsp_timeout) => {
 5964                                    lsp_timeout.await;
 5965                                    true
 5966                                },
 5967                                None => false,
 5968                            }
 5969                        }).fuse();
 5970                        let mut lsp_request = lsp_store.request_lsp(
 5971                            buffer.clone(),
 5972                            LanguageServerToQuery::Other(server_id),
 5973                            GetCompletions {
 5974                                position,
 5975                                context: context.clone(),
 5976                            },
 5977                            cx,
 5978                        ).fuse();
 5979                        let new_task = cx.background_spawn(async move {
 5980                            select_biased! {
 5981                                response = lsp_request => anyhow::Ok(Some(response?)),
 5982                                timeout_happened = timeout => {
 5983                                    if timeout_happened {
 5984                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5985                                        Ok(None)
 5986                                    } else {
 5987                                        let completions = lsp_request.await?;
 5988                                        Ok(Some(completions))
 5989                                    }
 5990                                },
 5991                            }
 5992                        });
 5993                        tasks.push((lsp_adapter, new_task));
 5994                    }
 5995                })?;
 5996
 5997                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5998                    let completion_response = task.await.ok()??;
 5999                    let completions = populate_labels_for_completions(
 6000                            completion_response.completions,
 6001                            language.clone(),
 6002                            lsp_adapter,
 6003                        )
 6004                        .await;
 6005                    Some(CompletionResponse {
 6006                        completions,
 6007                        is_incomplete: completion_response.is_incomplete,
 6008                    })
 6009                });
 6010
 6011                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6012
 6013                Ok(responses.into_iter().flatten().collect())
 6014            })
 6015        } else {
 6016            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6017        }
 6018    }
 6019
 6020    pub fn resolve_completions(
 6021        &self,
 6022        buffer: Entity<Buffer>,
 6023        completion_indices: Vec<usize>,
 6024        completions: Rc<RefCell<Box<[Completion]>>>,
 6025        cx: &mut Context<Self>,
 6026    ) -> Task<Result<bool>> {
 6027        let client = self.upstream_client();
 6028        let buffer_id = buffer.read(cx).remote_id();
 6029        let buffer_snapshot = buffer.read(cx).snapshot();
 6030
 6031        if !self.check_if_capable_for_proto_request(
 6032            &buffer,
 6033            GetCompletions::can_resolve_completions,
 6034            cx,
 6035        ) {
 6036            return Task::ready(Ok(false));
 6037        }
 6038        cx.spawn(async move |lsp_store, cx| {
 6039            let mut did_resolve = false;
 6040            if let Some((client, project_id)) = client {
 6041                for completion_index in completion_indices {
 6042                    let server_id = {
 6043                        let completion = &completions.borrow()[completion_index];
 6044                        completion.source.server_id()
 6045                    };
 6046                    if let Some(server_id) = server_id {
 6047                        if Self::resolve_completion_remote(
 6048                            project_id,
 6049                            server_id,
 6050                            buffer_id,
 6051                            completions.clone(),
 6052                            completion_index,
 6053                            client.clone(),
 6054                        )
 6055                        .await
 6056                        .log_err()
 6057                        .is_some()
 6058                        {
 6059                            did_resolve = true;
 6060                        }
 6061                    } else {
 6062                        resolve_word_completion(
 6063                            &buffer_snapshot,
 6064                            &mut completions.borrow_mut()[completion_index],
 6065                        );
 6066                    }
 6067                }
 6068            } else {
 6069                for completion_index in completion_indices {
 6070                    let server_id = {
 6071                        let completion = &completions.borrow()[completion_index];
 6072                        completion.source.server_id()
 6073                    };
 6074                    if let Some(server_id) = server_id {
 6075                        let server_and_adapter = lsp_store
 6076                            .read_with(cx, |lsp_store, _| {
 6077                                let server = lsp_store.language_server_for_id(server_id)?;
 6078                                let adapter =
 6079                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6080                                Some((server, adapter))
 6081                            })
 6082                            .ok()
 6083                            .flatten();
 6084                        let Some((server, adapter)) = server_and_adapter else {
 6085                            continue;
 6086                        };
 6087
 6088                        let resolved = Self::resolve_completion_local(
 6089                            server,
 6090                            completions.clone(),
 6091                            completion_index,
 6092                        )
 6093                        .await
 6094                        .log_err()
 6095                        .is_some();
 6096                        if resolved {
 6097                            Self::regenerate_completion_labels(
 6098                                adapter,
 6099                                &buffer_snapshot,
 6100                                completions.clone(),
 6101                                completion_index,
 6102                            )
 6103                            .await
 6104                            .log_err();
 6105                            did_resolve = true;
 6106                        }
 6107                    } else {
 6108                        resolve_word_completion(
 6109                            &buffer_snapshot,
 6110                            &mut completions.borrow_mut()[completion_index],
 6111                        );
 6112                    }
 6113                }
 6114            }
 6115
 6116            Ok(did_resolve)
 6117        })
 6118    }
 6119
 6120    async fn resolve_completion_local(
 6121        server: Arc<lsp::LanguageServer>,
 6122        completions: Rc<RefCell<Box<[Completion]>>>,
 6123        completion_index: usize,
 6124    ) -> Result<()> {
 6125        let server_id = server.server_id();
 6126        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6127            return Ok(());
 6128        }
 6129
 6130        let request = {
 6131            let completion = &completions.borrow()[completion_index];
 6132            match &completion.source {
 6133                CompletionSource::Lsp {
 6134                    lsp_completion,
 6135                    resolved,
 6136                    server_id: completion_server_id,
 6137                    ..
 6138                } => {
 6139                    if *resolved {
 6140                        return Ok(());
 6141                    }
 6142                    anyhow::ensure!(
 6143                        server_id == *completion_server_id,
 6144                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6145                    );
 6146                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6147                }
 6148                CompletionSource::BufferWord { .. }
 6149                | CompletionSource::Dap { .. }
 6150                | CompletionSource::Custom => {
 6151                    return Ok(());
 6152                }
 6153            }
 6154        };
 6155        let resolved_completion = request
 6156            .await
 6157            .into_response()
 6158            .context("resolve completion")?;
 6159
 6160        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6161        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6162
 6163        let mut completions = completions.borrow_mut();
 6164        let completion = &mut completions[completion_index];
 6165        if let CompletionSource::Lsp {
 6166            lsp_completion,
 6167            resolved,
 6168            server_id: completion_server_id,
 6169            ..
 6170        } = &mut completion.source
 6171        {
 6172            if *resolved {
 6173                return Ok(());
 6174            }
 6175            anyhow::ensure!(
 6176                server_id == *completion_server_id,
 6177                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6178            );
 6179            *lsp_completion = Box::new(resolved_completion);
 6180            *resolved = true;
 6181        }
 6182        Ok(())
 6183    }
 6184
 6185    async fn regenerate_completion_labels(
 6186        adapter: Arc<CachedLspAdapter>,
 6187        snapshot: &BufferSnapshot,
 6188        completions: Rc<RefCell<Box<[Completion]>>>,
 6189        completion_index: usize,
 6190    ) -> Result<()> {
 6191        let completion_item = completions.borrow()[completion_index]
 6192            .source
 6193            .lsp_completion(true)
 6194            .map(Cow::into_owned);
 6195        if let Some(lsp_documentation) = completion_item
 6196            .as_ref()
 6197            .and_then(|completion_item| completion_item.documentation.clone())
 6198        {
 6199            let mut completions = completions.borrow_mut();
 6200            let completion = &mut completions[completion_index];
 6201            completion.documentation = Some(lsp_documentation.into());
 6202        } else {
 6203            let mut completions = completions.borrow_mut();
 6204            let completion = &mut completions[completion_index];
 6205            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6206        }
 6207
 6208        let mut new_label = match completion_item {
 6209            Some(completion_item) => {
 6210                // 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
 6211                // So we have to update the label here anyway...
 6212                let language = snapshot.language();
 6213                match language {
 6214                    Some(language) => {
 6215                        adapter
 6216                            .labels_for_completions(
 6217                                std::slice::from_ref(&completion_item),
 6218                                language,
 6219                            )
 6220                            .await?
 6221                    }
 6222                    None => Vec::new(),
 6223                }
 6224                .pop()
 6225                .flatten()
 6226                .unwrap_or_else(|| {
 6227                    CodeLabel::fallback_for_completion(
 6228                        &completion_item,
 6229                        language.map(|language| language.as_ref()),
 6230                    )
 6231                })
 6232            }
 6233            None => CodeLabel::plain(
 6234                completions.borrow()[completion_index].new_text.clone(),
 6235                None,
 6236            ),
 6237        };
 6238        ensure_uniform_list_compatible_label(&mut new_label);
 6239
 6240        let mut completions = completions.borrow_mut();
 6241        let completion = &mut completions[completion_index];
 6242        if completion.label.filter_text() == new_label.filter_text() {
 6243            completion.label = new_label;
 6244        } else {
 6245            log::error!(
 6246                "Resolved completion changed display label from {} to {}. \
 6247                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6248                completion.label.text(),
 6249                new_label.text(),
 6250                completion.label.filter_text(),
 6251                new_label.filter_text()
 6252            );
 6253        }
 6254
 6255        Ok(())
 6256    }
 6257
 6258    async fn resolve_completion_remote(
 6259        project_id: u64,
 6260        server_id: LanguageServerId,
 6261        buffer_id: BufferId,
 6262        completions: Rc<RefCell<Box<[Completion]>>>,
 6263        completion_index: usize,
 6264        client: AnyProtoClient,
 6265    ) -> Result<()> {
 6266        let lsp_completion = {
 6267            let completion = &completions.borrow()[completion_index];
 6268            match &completion.source {
 6269                CompletionSource::Lsp {
 6270                    lsp_completion,
 6271                    resolved,
 6272                    server_id: completion_server_id,
 6273                    ..
 6274                } => {
 6275                    anyhow::ensure!(
 6276                        server_id == *completion_server_id,
 6277                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6278                    );
 6279                    if *resolved {
 6280                        return Ok(());
 6281                    }
 6282                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6283                }
 6284                CompletionSource::Custom
 6285                | CompletionSource::Dap { .. }
 6286                | CompletionSource::BufferWord { .. } => {
 6287                    return Ok(());
 6288                }
 6289            }
 6290        };
 6291        let request = proto::ResolveCompletionDocumentation {
 6292            project_id,
 6293            language_server_id: server_id.0 as u64,
 6294            lsp_completion,
 6295            buffer_id: buffer_id.into(),
 6296        };
 6297
 6298        let response = client
 6299            .request(request)
 6300            .await
 6301            .context("completion documentation resolve proto request")?;
 6302        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6303
 6304        let documentation = if response.documentation.is_empty() {
 6305            CompletionDocumentation::Undocumented
 6306        } else if response.documentation_is_markdown {
 6307            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6308        } else if response.documentation.lines().count() <= 1 {
 6309            CompletionDocumentation::SingleLine(response.documentation.into())
 6310        } else {
 6311            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6312        };
 6313
 6314        let mut completions = completions.borrow_mut();
 6315        let completion = &mut completions[completion_index];
 6316        completion.documentation = Some(documentation);
 6317        if let CompletionSource::Lsp {
 6318            insert_range,
 6319            lsp_completion,
 6320            resolved,
 6321            server_id: completion_server_id,
 6322            lsp_defaults: _,
 6323        } = &mut completion.source
 6324        {
 6325            let completion_insert_range = response
 6326                .old_insert_start
 6327                .and_then(deserialize_anchor)
 6328                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6329            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6330
 6331            if *resolved {
 6332                return Ok(());
 6333            }
 6334            anyhow::ensure!(
 6335                server_id == *completion_server_id,
 6336                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6337            );
 6338            *lsp_completion = Box::new(resolved_lsp_completion);
 6339            *resolved = true;
 6340        }
 6341
 6342        let replace_range = response
 6343            .old_replace_start
 6344            .and_then(deserialize_anchor)
 6345            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6346        if let Some((old_replace_start, old_replace_end)) = replace_range
 6347            && !response.new_text.is_empty()
 6348        {
 6349            completion.new_text = response.new_text;
 6350            completion.replace_range = old_replace_start..old_replace_end;
 6351        }
 6352
 6353        Ok(())
 6354    }
 6355
 6356    pub fn apply_additional_edits_for_completion(
 6357        &self,
 6358        buffer_handle: Entity<Buffer>,
 6359        completions: Rc<RefCell<Box<[Completion]>>>,
 6360        completion_index: usize,
 6361        push_to_history: bool,
 6362        cx: &mut Context<Self>,
 6363    ) -> Task<Result<Option<Transaction>>> {
 6364        if let Some((client, project_id)) = self.upstream_client() {
 6365            let buffer = buffer_handle.read(cx);
 6366            let buffer_id = buffer.remote_id();
 6367            cx.spawn(async move |_, cx| {
 6368                let request = {
 6369                    let completion = completions.borrow()[completion_index].clone();
 6370                    proto::ApplyCompletionAdditionalEdits {
 6371                        project_id,
 6372                        buffer_id: buffer_id.into(),
 6373                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6374                            replace_range: completion.replace_range,
 6375                            new_text: completion.new_text,
 6376                            source: completion.source,
 6377                        })),
 6378                    }
 6379                };
 6380
 6381                if let Some(transaction) = client.request(request).await?.transaction {
 6382                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6383                    buffer_handle
 6384                        .update(cx, |buffer, _| {
 6385                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6386                        })?
 6387                        .await?;
 6388                    if push_to_history {
 6389                        buffer_handle.update(cx, |buffer, _| {
 6390                            buffer.push_transaction(transaction.clone(), Instant::now());
 6391                            buffer.finalize_last_transaction();
 6392                        })?;
 6393                    }
 6394                    Ok(Some(transaction))
 6395                } else {
 6396                    Ok(None)
 6397                }
 6398            })
 6399        } else {
 6400            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6401                let completion = &completions.borrow()[completion_index];
 6402                let server_id = completion.source.server_id()?;
 6403                Some(
 6404                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6405                        .1
 6406                        .clone(),
 6407                )
 6408            }) else {
 6409                return Task::ready(Ok(None));
 6410            };
 6411
 6412            cx.spawn(async move |this, cx| {
 6413                Self::resolve_completion_local(
 6414                    server.clone(),
 6415                    completions.clone(),
 6416                    completion_index,
 6417                )
 6418                .await
 6419                .context("resolving completion")?;
 6420                let completion = completions.borrow()[completion_index].clone();
 6421                let additional_text_edits = completion
 6422                    .source
 6423                    .lsp_completion(true)
 6424                    .as_ref()
 6425                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6426                if let Some(edits) = additional_text_edits {
 6427                    let edits = this
 6428                        .update(cx, |this, cx| {
 6429                            this.as_local_mut().unwrap().edits_from_lsp(
 6430                                &buffer_handle,
 6431                                edits,
 6432                                server.server_id(),
 6433                                None,
 6434                                cx,
 6435                            )
 6436                        })?
 6437                        .await?;
 6438
 6439                    buffer_handle.update(cx, |buffer, cx| {
 6440                        buffer.finalize_last_transaction();
 6441                        buffer.start_transaction();
 6442
 6443                        for (range, text) in edits {
 6444                            let primary = &completion.replace_range;
 6445                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6446                                && primary.end.cmp(&range.start, buffer).is_ge();
 6447                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6448                                && range.end.cmp(&primary.end, buffer).is_ge();
 6449
 6450                            //Skip additional edits which overlap with the primary completion edit
 6451                            //https://github.com/zed-industries/zed/pull/1871
 6452                            if !start_within && !end_within {
 6453                                buffer.edit([(range, text)], None, cx);
 6454                            }
 6455                        }
 6456
 6457                        let transaction = if buffer.end_transaction(cx).is_some() {
 6458                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6459                            if !push_to_history {
 6460                                buffer.forget_transaction(transaction.id);
 6461                            }
 6462                            Some(transaction)
 6463                        } else {
 6464                            None
 6465                        };
 6466                        Ok(transaction)
 6467                    })?
 6468                } else {
 6469                    Ok(None)
 6470                }
 6471            })
 6472        }
 6473    }
 6474
 6475    pub fn pull_diagnostics(
 6476        &mut self,
 6477        buffer: Entity<Buffer>,
 6478        cx: &mut Context<Self>,
 6479    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6480        let buffer_id = buffer.read(cx).remote_id();
 6481
 6482        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6483            if !self.is_capable_for_proto_request(
 6484                &buffer,
 6485                &GetDocumentDiagnostics {
 6486                    previous_result_id: None,
 6487                },
 6488                cx,
 6489            ) {
 6490                return Task::ready(Ok(None));
 6491            }
 6492            let request_task = client.request(proto::MultiLspQuery {
 6493                buffer_id: buffer_id.to_proto(),
 6494                version: serialize_version(&buffer.read(cx).version()),
 6495                project_id: upstream_project_id,
 6496                strategy: Some(proto::multi_lsp_query::Strategy::All(
 6497                    proto::AllLanguageServers {},
 6498                )),
 6499                request: Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(
 6500                    proto::GetDocumentDiagnostics {
 6501                        project_id: upstream_project_id,
 6502                        buffer_id: buffer_id.to_proto(),
 6503                        version: serialize_version(&buffer.read(cx).version()),
 6504                    },
 6505                )),
 6506            });
 6507            cx.background_spawn(async move {
 6508                let _proto_responses = request_task
 6509                    .await?
 6510                    .responses
 6511                    .into_iter()
 6512                    .filter_map(|lsp_response| match lsp_response.response? {
 6513                        proto::lsp_response::Response::GetDocumentDiagnosticsResponse(response) => {
 6514                            Some(response)
 6515                        }
 6516                        unexpected => {
 6517                            debug_panic!("Unexpected response: {unexpected:?}");
 6518                            None
 6519                        }
 6520                    })
 6521                    .collect::<Vec<_>>();
 6522                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6523                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6524                // Do not attempt to further process the dummy responses here.
 6525                Ok(None)
 6526            })
 6527        } else {
 6528            let server_ids = buffer.update(cx, |buffer, cx| {
 6529                self.language_servers_for_local_buffer(buffer, cx)
 6530                    .map(|(_, server)| server.server_id())
 6531                    .collect::<Vec<_>>()
 6532            });
 6533            let pull_diagnostics = server_ids
 6534                .into_iter()
 6535                .map(|server_id| {
 6536                    let result_id = self.result_id(server_id, buffer_id, cx);
 6537                    self.request_lsp(
 6538                        buffer.clone(),
 6539                        LanguageServerToQuery::Other(server_id),
 6540                        GetDocumentDiagnostics {
 6541                            previous_result_id: result_id,
 6542                        },
 6543                        cx,
 6544                    )
 6545                })
 6546                .collect::<Vec<_>>();
 6547
 6548            cx.background_spawn(async move {
 6549                let mut responses = Vec::new();
 6550                for diagnostics in join_all(pull_diagnostics).await {
 6551                    responses.extend(diagnostics?);
 6552                }
 6553                Ok(Some(responses))
 6554            })
 6555        }
 6556    }
 6557
 6558    pub fn inlay_hints(
 6559        &mut self,
 6560        buffer: Entity<Buffer>,
 6561        range: Range<Anchor>,
 6562        cx: &mut Context<Self>,
 6563    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6564        let range_start = range.start;
 6565        let range_end = range.end;
 6566        let buffer_id = buffer.read(cx).remote_id().into();
 6567        let request = InlayHints { range };
 6568
 6569        if let Some((client, project_id)) = self.upstream_client() {
 6570            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6571                return Task::ready(Ok(Vec::new()));
 6572            }
 6573            let proto_request = proto::InlayHints {
 6574                project_id,
 6575                buffer_id,
 6576                start: Some(serialize_anchor(&range_start)),
 6577                end: Some(serialize_anchor(&range_end)),
 6578                version: serialize_version(&buffer.read(cx).version()),
 6579            };
 6580            cx.spawn(async move |project, cx| {
 6581                let response = client
 6582                    .request(proto_request)
 6583                    .await
 6584                    .context("inlay hints proto request")?;
 6585                LspCommand::response_from_proto(
 6586                    request,
 6587                    response,
 6588                    project.upgrade().context("No project")?,
 6589                    buffer.clone(),
 6590                    cx.clone(),
 6591                )
 6592                .await
 6593                .context("inlay hints proto response conversion")
 6594            })
 6595        } else {
 6596            let lsp_request_task = self.request_lsp(
 6597                buffer.clone(),
 6598                LanguageServerToQuery::FirstCapable,
 6599                request,
 6600                cx,
 6601            );
 6602            cx.spawn(async move |_, cx| {
 6603                buffer
 6604                    .update(cx, |buffer, _| {
 6605                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6606                    })?
 6607                    .await
 6608                    .context("waiting for inlay hint request range edits")?;
 6609                lsp_request_task.await.context("inlay hints LSP request")
 6610            })
 6611        }
 6612    }
 6613
 6614    pub fn pull_diagnostics_for_buffer(
 6615        &mut self,
 6616        buffer: Entity<Buffer>,
 6617        cx: &mut Context<Self>,
 6618    ) -> Task<anyhow::Result<()>> {
 6619        let diagnostics = self.pull_diagnostics(buffer, cx);
 6620        cx.spawn(async move |lsp_store, cx| {
 6621            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6622                return Ok(());
 6623            };
 6624            lsp_store.update(cx, |lsp_store, cx| {
 6625                if lsp_store.as_local().is_none() {
 6626                    return;
 6627                }
 6628
 6629                let mut unchanged_buffers = HashSet::default();
 6630                let mut changed_buffers = HashSet::default();
 6631                let server_diagnostics_updates = diagnostics
 6632                    .into_iter()
 6633                    .filter_map(|diagnostics_set| match diagnostics_set {
 6634                        LspPullDiagnostics::Response {
 6635                            server_id,
 6636                            uri,
 6637                            diagnostics,
 6638                        } => Some((server_id, uri, diagnostics)),
 6639                        LspPullDiagnostics::Default => None,
 6640                    })
 6641                    .fold(
 6642                        HashMap::default(),
 6643                        |mut acc, (server_id, uri, diagnostics)| {
 6644                            let (result_id, diagnostics) = match diagnostics {
 6645                                PulledDiagnostics::Unchanged { result_id } => {
 6646                                    unchanged_buffers.insert(uri.clone());
 6647                                    (Some(result_id), Vec::new())
 6648                                }
 6649                                PulledDiagnostics::Changed {
 6650                                    result_id,
 6651                                    diagnostics,
 6652                                } => {
 6653                                    changed_buffers.insert(uri.clone());
 6654                                    (result_id, diagnostics)
 6655                                }
 6656                            };
 6657                            let disk_based_sources = Cow::Owned(
 6658                                lsp_store
 6659                                    .language_server_adapter_for_id(server_id)
 6660                                    .as_ref()
 6661                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6662                                    .unwrap_or(&[])
 6663                                    .to_vec(),
 6664                            );
 6665                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6666                                DocumentDiagnosticsUpdate {
 6667                                    server_id,
 6668                                    diagnostics: lsp::PublishDiagnosticsParams {
 6669                                        uri,
 6670                                        diagnostics,
 6671                                        version: None,
 6672                                    },
 6673                                    result_id,
 6674                                    disk_based_sources,
 6675                                },
 6676                            );
 6677                            acc
 6678                        },
 6679                    );
 6680
 6681                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6682                    lsp_store
 6683                        .merge_lsp_diagnostics(
 6684                            DiagnosticSourceKind::Pulled,
 6685                            diagnostic_updates,
 6686                            |buffer, old_diagnostic, cx| {
 6687                                File::from_dyn(buffer.file())
 6688                                    .and_then(|file| {
 6689                                        let abs_path = file.as_local()?.abs_path(cx);
 6690                                        lsp::Url::from_file_path(abs_path).ok()
 6691                                    })
 6692                                    .is_none_or(|buffer_uri| {
 6693                                        unchanged_buffers.contains(&buffer_uri)
 6694                                            || match old_diagnostic.source_kind {
 6695                                                DiagnosticSourceKind::Pulled => {
 6696                                                    !changed_buffers.contains(&buffer_uri)
 6697                                                }
 6698                                                DiagnosticSourceKind::Other
 6699                                                | DiagnosticSourceKind::Pushed => true,
 6700                                            }
 6701                                    })
 6702                            },
 6703                            cx,
 6704                        )
 6705                        .log_err();
 6706                }
 6707            })
 6708        })
 6709    }
 6710
 6711    pub fn document_colors(
 6712        &mut self,
 6713        fetch_strategy: LspFetchStrategy,
 6714        buffer: Entity<Buffer>,
 6715        cx: &mut Context<Self>,
 6716    ) -> Option<DocumentColorTask> {
 6717        let version_queried_for = buffer.read(cx).version();
 6718        let buffer_id = buffer.read(cx).remote_id();
 6719
 6720        match fetch_strategy {
 6721            LspFetchStrategy::IgnoreCache => {}
 6722            LspFetchStrategy::UseCache {
 6723                known_cache_version,
 6724            } => {
 6725                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6726                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6727                {
 6728                    let has_different_servers = self.as_local().is_some_and(|local| {
 6729                        local
 6730                            .buffers_opened_in_servers
 6731                            .get(&buffer_id)
 6732                            .cloned()
 6733                            .unwrap_or_default()
 6734                            != cached_data.colors.keys().copied().collect()
 6735                    });
 6736                    if !has_different_servers {
 6737                        if Some(cached_data.cache_version) == known_cache_version {
 6738                            return None;
 6739                        } else {
 6740                            return Some(
 6741                                Task::ready(Ok(DocumentColors {
 6742                                    colors: cached_data
 6743                                        .colors
 6744                                        .values()
 6745                                        .flatten()
 6746                                        .cloned()
 6747                                        .collect(),
 6748                                    cache_version: Some(cached_data.cache_version),
 6749                                }))
 6750                                .shared(),
 6751                            );
 6752                        }
 6753                    }
 6754                }
 6755            }
 6756        }
 6757
 6758        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6759        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6760            && !version_queried_for.changed_since(updating_for)
 6761        {
 6762            return Some(running_update.clone());
 6763        }
 6764        let query_version_queried_for = version_queried_for.clone();
 6765        let new_task = cx
 6766            .spawn(async move |lsp_store, cx| {
 6767                cx.background_executor()
 6768                    .timer(Duration::from_millis(30))
 6769                    .await;
 6770                let fetched_colors = lsp_store
 6771                    .update(cx, |lsp_store, cx| {
 6772                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6773                    })?
 6774                    .await
 6775                    .context("fetching document colors")
 6776                    .map_err(Arc::new);
 6777                let fetched_colors = match fetched_colors {
 6778                    Ok(fetched_colors) => {
 6779                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6780                            && Some(true)
 6781                                == buffer
 6782                                    .update(cx, |buffer, _| {
 6783                                        buffer.version() != query_version_queried_for
 6784                                    })
 6785                                    .ok()
 6786                        {
 6787                            return Ok(DocumentColors::default());
 6788                        }
 6789                        fetched_colors
 6790                    }
 6791                    Err(e) => {
 6792                        lsp_store
 6793                            .update(cx, |lsp_store, _| {
 6794                                lsp_store
 6795                                    .lsp_document_colors
 6796                                    .entry(buffer_id)
 6797                                    .or_default()
 6798                                    .colors_update = None;
 6799                            })
 6800                            .ok();
 6801                        return Err(e);
 6802                    }
 6803                };
 6804
 6805                lsp_store
 6806                    .update(cx, |lsp_store, _| {
 6807                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6808
 6809                        if lsp_data.colors_for_version == query_version_queried_for {
 6810                            lsp_data.colors.extend(fetched_colors.clone());
 6811                            lsp_data.cache_version += 1;
 6812                        } else if !lsp_data
 6813                            .colors_for_version
 6814                            .changed_since(&query_version_queried_for)
 6815                        {
 6816                            lsp_data.colors_for_version = query_version_queried_for;
 6817                            lsp_data.colors = fetched_colors.clone();
 6818                            lsp_data.cache_version += 1;
 6819                        }
 6820                        lsp_data.colors_update = None;
 6821                        let colors = lsp_data
 6822                            .colors
 6823                            .values()
 6824                            .flatten()
 6825                            .cloned()
 6826                            .collect::<HashSet<_>>();
 6827                        DocumentColors {
 6828                            colors,
 6829                            cache_version: Some(lsp_data.cache_version),
 6830                        }
 6831                    })
 6832                    .map_err(Arc::new)
 6833            })
 6834            .shared();
 6835        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6836        Some(new_task)
 6837    }
 6838
 6839    fn fetch_document_colors_for_buffer(
 6840        &mut self,
 6841        buffer: &Entity<Buffer>,
 6842        cx: &mut Context<Self>,
 6843    ) -> Task<anyhow::Result<HashMap<LanguageServerId, HashSet<DocumentColor>>>> {
 6844        if let Some((client, project_id)) = self.upstream_client() {
 6845            let request = GetDocumentColor {};
 6846            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6847                return Task::ready(Ok(HashMap::default()));
 6848            }
 6849
 6850            let request_task = client.request(proto::MultiLspQuery {
 6851                project_id,
 6852                buffer_id: buffer.read(cx).remote_id().to_proto(),
 6853                version: serialize_version(&buffer.read(cx).version()),
 6854                strategy: Some(proto::multi_lsp_query::Strategy::All(
 6855                    proto::AllLanguageServers {},
 6856                )),
 6857                request: Some(proto::multi_lsp_query::Request::GetDocumentColor(
 6858                    request.to_proto(project_id, buffer.read(cx)),
 6859                )),
 6860            });
 6861            let buffer = buffer.clone();
 6862            cx.spawn(async move |project, cx| {
 6863                let Some(project) = project.upgrade() else {
 6864                    return Ok(HashMap::default());
 6865                };
 6866                let colors = join_all(
 6867                    request_task
 6868                        .await
 6869                        .log_err()
 6870                        .map(|response| response.responses)
 6871                        .unwrap_or_default()
 6872                        .into_iter()
 6873                        .filter_map(|lsp_response| match lsp_response.response? {
 6874                            proto::lsp_response::Response::GetDocumentColorResponse(response) => {
 6875                                Some((
 6876                                    LanguageServerId::from_proto(lsp_response.server_id),
 6877                                    response,
 6878                                ))
 6879                            }
 6880                            unexpected => {
 6881                                debug_panic!("Unexpected response: {unexpected:?}");
 6882                                None
 6883                            }
 6884                        })
 6885                        .map(|(server_id, color_response)| {
 6886                            let response = request.response_from_proto(
 6887                                color_response,
 6888                                project.clone(),
 6889                                buffer.clone(),
 6890                                cx.clone(),
 6891                            );
 6892                            async move { (server_id, response.await.log_err().unwrap_or_default()) }
 6893                        }),
 6894                )
 6895                .await
 6896                .into_iter()
 6897                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6898                    acc.entry(server_id)
 6899                        .or_insert_with(HashSet::default)
 6900                        .extend(colors);
 6901                    acc
 6902                });
 6903                Ok(colors)
 6904            })
 6905        } else {
 6906            let document_colors_task =
 6907                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6908            cx.background_spawn(async move {
 6909                Ok(document_colors_task
 6910                    .await
 6911                    .into_iter()
 6912                    .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6913                        acc.entry(server_id)
 6914                            .or_insert_with(HashSet::default)
 6915                            .extend(colors);
 6916                        acc
 6917                    })
 6918                    .into_iter()
 6919                    .collect())
 6920            })
 6921        }
 6922    }
 6923
 6924    pub fn signature_help<T: ToPointUtf16>(
 6925        &mut self,
 6926        buffer: &Entity<Buffer>,
 6927        position: T,
 6928        cx: &mut Context<Self>,
 6929    ) -> Task<Vec<SignatureHelp>> {
 6930        let position = position.to_point_utf16(buffer.read(cx));
 6931
 6932        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6933            let request = GetSignatureHelp { position };
 6934            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6935                return Task::ready(Vec::new());
 6936            }
 6937            let request_task = client.request(proto::MultiLspQuery {
 6938                buffer_id: buffer.read(cx).remote_id().into(),
 6939                version: serialize_version(&buffer.read(cx).version()),
 6940                project_id: upstream_project_id,
 6941                strategy: Some(proto::multi_lsp_query::Strategy::All(
 6942                    proto::AllLanguageServers {},
 6943                )),
 6944                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
 6945                    request.to_proto(upstream_project_id, buffer.read(cx)),
 6946                )),
 6947            });
 6948            let buffer = buffer.clone();
 6949            cx.spawn(async move |weak_project, cx| {
 6950                let Some(project) = weak_project.upgrade() else {
 6951                    return Vec::new();
 6952                };
 6953                join_all(
 6954                    request_task
 6955                        .await
 6956                        .log_err()
 6957                        .map(|response| response.responses)
 6958                        .unwrap_or_default()
 6959                        .into_iter()
 6960                        .filter_map(|lsp_response| match lsp_response.response? {
 6961                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
 6962                                Some(response)
 6963                            }
 6964                            unexpected => {
 6965                                debug_panic!("Unexpected response: {unexpected:?}");
 6966                                None
 6967                            }
 6968                        })
 6969                        .map(|signature_response| {
 6970                            let response = GetSignatureHelp { position }.response_from_proto(
 6971                                signature_response,
 6972                                project.clone(),
 6973                                buffer.clone(),
 6974                                cx.clone(),
 6975                            );
 6976                            async move { response.await.log_err().flatten() }
 6977                        }),
 6978                )
 6979                .await
 6980                .into_iter()
 6981                .flatten()
 6982                .collect()
 6983            })
 6984        } else {
 6985            let all_actions_task = self.request_multiple_lsp_locally(
 6986                buffer,
 6987                Some(position),
 6988                GetSignatureHelp { position },
 6989                cx,
 6990            );
 6991            cx.background_spawn(async move {
 6992                all_actions_task
 6993                    .await
 6994                    .into_iter()
 6995                    .flat_map(|(_, actions)| actions)
 6996                    .collect::<Vec<_>>()
 6997            })
 6998        }
 6999    }
 7000
 7001    pub fn hover(
 7002        &mut self,
 7003        buffer: &Entity<Buffer>,
 7004        position: PointUtf16,
 7005        cx: &mut Context<Self>,
 7006    ) -> Task<Vec<Hover>> {
 7007        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7008            let request = GetHover { position };
 7009            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7010                return Task::ready(Vec::new());
 7011            }
 7012            let request_task = client.request(proto::MultiLspQuery {
 7013                buffer_id: buffer.read(cx).remote_id().into(),
 7014                version: serialize_version(&buffer.read(cx).version()),
 7015                project_id: upstream_project_id,
 7016                strategy: Some(proto::multi_lsp_query::Strategy::All(
 7017                    proto::AllLanguageServers {},
 7018                )),
 7019                request: Some(proto::multi_lsp_query::Request::GetHover(
 7020                    request.to_proto(upstream_project_id, buffer.read(cx)),
 7021                )),
 7022            });
 7023            let buffer = buffer.clone();
 7024            cx.spawn(async move |weak_project, cx| {
 7025                let Some(project) = weak_project.upgrade() else {
 7026                    return Vec::new();
 7027                };
 7028                join_all(
 7029                    request_task
 7030                        .await
 7031                        .log_err()
 7032                        .map(|response| response.responses)
 7033                        .unwrap_or_default()
 7034                        .into_iter()
 7035                        .filter_map(|lsp_response| match lsp_response.response? {
 7036                            proto::lsp_response::Response::GetHoverResponse(response) => {
 7037                                Some(response)
 7038                            }
 7039                            unexpected => {
 7040                                debug_panic!("Unexpected response: {unexpected:?}");
 7041                                None
 7042                            }
 7043                        })
 7044                        .map(|hover_response| {
 7045                            let response = GetHover { position }.response_from_proto(
 7046                                hover_response,
 7047                                project.clone(),
 7048                                buffer.clone(),
 7049                                cx.clone(),
 7050                            );
 7051                            async move {
 7052                                response
 7053                                    .await
 7054                                    .log_err()
 7055                                    .flatten()
 7056                                    .and_then(remove_empty_hover_blocks)
 7057                            }
 7058                        }),
 7059                )
 7060                .await
 7061                .into_iter()
 7062                .flatten()
 7063                .collect()
 7064            })
 7065        } else {
 7066            let all_actions_task = self.request_multiple_lsp_locally(
 7067                buffer,
 7068                Some(position),
 7069                GetHover { position },
 7070                cx,
 7071            );
 7072            cx.background_spawn(async move {
 7073                all_actions_task
 7074                    .await
 7075                    .into_iter()
 7076                    .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7077                    .collect::<Vec<Hover>>()
 7078            })
 7079        }
 7080    }
 7081
 7082    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7083        let language_registry = self.languages.clone();
 7084
 7085        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7086            let request = upstream_client.request(proto::GetProjectSymbols {
 7087                project_id: *project_id,
 7088                query: query.to_string(),
 7089            });
 7090            cx.foreground_executor().spawn(async move {
 7091                let response = request.await?;
 7092                let mut symbols = Vec::new();
 7093                let core_symbols = response
 7094                    .symbols
 7095                    .into_iter()
 7096                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7097                    .collect::<Vec<_>>();
 7098                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7099                    .await;
 7100                Ok(symbols)
 7101            })
 7102        } else if let Some(local) = self.as_local() {
 7103            struct WorkspaceSymbolsResult {
 7104                server_id: LanguageServerId,
 7105                lsp_adapter: Arc<CachedLspAdapter>,
 7106                worktree: WeakEntity<Worktree>,
 7107                worktree_abs_path: Arc<Path>,
 7108                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7109            }
 7110
 7111            let mut requests = Vec::new();
 7112            let mut requested_servers = BTreeSet::new();
 7113            for (seed, state) in local.language_server_ids.iter() {
 7114                let Some(worktree_handle) = self
 7115                    .worktree_store
 7116                    .read(cx)
 7117                    .worktree_for_id(seed.worktree_id, cx)
 7118                else {
 7119                    continue;
 7120                };
 7121                let worktree = worktree_handle.read(cx);
 7122                if !worktree.is_visible() {
 7123                    continue;
 7124                }
 7125
 7126                if !requested_servers.insert(state.id) {
 7127                    continue;
 7128                }
 7129
 7130                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7131                    Some(LanguageServerState::Running {
 7132                        adapter, server, ..
 7133                    }) => (adapter.clone(), server),
 7134
 7135                    _ => continue,
 7136                };
 7137                let supports_workspace_symbol_request =
 7138                    match server.capabilities().workspace_symbol_provider {
 7139                        Some(OneOf::Left(supported)) => supported,
 7140                        Some(OneOf::Right(_)) => true,
 7141                        None => false,
 7142                    };
 7143                if !supports_workspace_symbol_request {
 7144                    continue;
 7145                }
 7146                let worktree_abs_path = worktree.abs_path().clone();
 7147                let worktree_handle = worktree_handle.clone();
 7148                let server_id = server.server_id();
 7149                requests.push(
 7150                        server
 7151                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7152                                lsp::WorkspaceSymbolParams {
 7153                                    query: query.to_string(),
 7154                                    ..Default::default()
 7155                                },
 7156                            )
 7157                            .map(move |response| {
 7158                                let lsp_symbols = response.into_response()
 7159                                    .context("workspace symbols request")
 7160                                    .log_err()
 7161                                    .flatten()
 7162                                    .map(|symbol_response| match symbol_response {
 7163                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7164                                            flat_responses.into_iter().map(|lsp_symbol| {
 7165                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7166                                            }).collect::<Vec<_>>()
 7167                                        }
 7168                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7169                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7170                                                let location = match lsp_symbol.location {
 7171                                                    OneOf::Left(location) => location,
 7172                                                    OneOf::Right(_) => {
 7173                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7174                                                        return None
 7175                                                    }
 7176                                                };
 7177                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7178                                            }).collect::<Vec<_>>()
 7179                                        }
 7180                                    }).unwrap_or_default();
 7181
 7182                                WorkspaceSymbolsResult {
 7183                                    server_id,
 7184                                    lsp_adapter,
 7185                                    worktree: worktree_handle.downgrade(),
 7186                                    worktree_abs_path,
 7187                                    lsp_symbols,
 7188                                }
 7189                            }),
 7190                    );
 7191            }
 7192
 7193            cx.spawn(async move |this, cx| {
 7194                let responses = futures::future::join_all(requests).await;
 7195                let this = match this.upgrade() {
 7196                    Some(this) => this,
 7197                    None => return Ok(Vec::new()),
 7198                };
 7199
 7200                let mut symbols = Vec::new();
 7201                for result in responses {
 7202                    let core_symbols = this.update(cx, |this, cx| {
 7203                        result
 7204                            .lsp_symbols
 7205                            .into_iter()
 7206                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7207                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7208                                let source_worktree = result.worktree.upgrade()?;
 7209                                let source_worktree_id = source_worktree.read(cx).id();
 7210
 7211                                let path;
 7212                                let worktree;
 7213                                if let Some((tree, rel_path)) =
 7214                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7215                                {
 7216                                    worktree = tree;
 7217                                    path = rel_path;
 7218                                } else {
 7219                                    worktree = source_worktree;
 7220                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7221                                }
 7222
 7223                                let worktree_id = worktree.read(cx).id();
 7224                                let project_path = ProjectPath {
 7225                                    worktree_id,
 7226                                    path: path.into(),
 7227                                };
 7228                                let signature = this.symbol_signature(&project_path);
 7229                                Some(CoreSymbol {
 7230                                    source_language_server_id: result.server_id,
 7231                                    language_server_name: result.lsp_adapter.name.clone(),
 7232                                    source_worktree_id,
 7233                                    path: project_path,
 7234                                    kind: symbol_kind,
 7235                                    name: symbol_name,
 7236                                    range: range_from_lsp(symbol_location.range),
 7237                                    signature,
 7238                                })
 7239                            })
 7240                            .collect()
 7241                    })?;
 7242
 7243                    populate_labels_for_symbols(
 7244                        core_symbols,
 7245                        &language_registry,
 7246                        Some(result.lsp_adapter),
 7247                        &mut symbols,
 7248                    )
 7249                    .await;
 7250                }
 7251
 7252                Ok(symbols)
 7253            })
 7254        } else {
 7255            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7256        }
 7257    }
 7258
 7259    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7260        let mut summary = DiagnosticSummary::default();
 7261        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7262            summary.error_count += path_summary.error_count;
 7263            summary.warning_count += path_summary.warning_count;
 7264        }
 7265        summary
 7266    }
 7267
 7268    pub fn diagnostic_summaries<'a>(
 7269        &'a self,
 7270        include_ignored: bool,
 7271        cx: &'a App,
 7272    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7273        self.worktree_store
 7274            .read(cx)
 7275            .visible_worktrees(cx)
 7276            .filter_map(|worktree| {
 7277                let worktree = worktree.read(cx);
 7278                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7279            })
 7280            .flat_map(move |(worktree, summaries)| {
 7281                let worktree_id = worktree.id();
 7282                summaries
 7283                    .iter()
 7284                    .filter(move |(path, _)| {
 7285                        include_ignored
 7286                            || worktree
 7287                                .entry_for_path(path.as_ref())
 7288                                .is_some_and(|entry| !entry.is_ignored)
 7289                    })
 7290                    .flat_map(move |(path, summaries)| {
 7291                        summaries.iter().map(move |(server_id, summary)| {
 7292                            (
 7293                                ProjectPath {
 7294                                    worktree_id,
 7295                                    path: path.clone(),
 7296                                },
 7297                                *server_id,
 7298                                *summary,
 7299                            )
 7300                        })
 7301                    })
 7302            })
 7303    }
 7304
 7305    pub fn on_buffer_edited(
 7306        &mut self,
 7307        buffer: Entity<Buffer>,
 7308        cx: &mut Context<Self>,
 7309    ) -> Option<()> {
 7310        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7311            Some(
 7312                self.as_local()?
 7313                    .language_servers_for_buffer(buffer, cx)
 7314                    .map(|i| i.1.clone())
 7315                    .collect(),
 7316            )
 7317        })?;
 7318
 7319        let buffer = buffer.read(cx);
 7320        let file = File::from_dyn(buffer.file())?;
 7321        let abs_path = file.as_local()?.abs_path(cx);
 7322        let uri = lsp::Url::from_file_path(abs_path).unwrap();
 7323        let next_snapshot = buffer.text_snapshot();
 7324        for language_server in language_servers {
 7325            let language_server = language_server.clone();
 7326
 7327            let buffer_snapshots = self
 7328                .as_local_mut()
 7329                .unwrap()
 7330                .buffer_snapshots
 7331                .get_mut(&buffer.remote_id())
 7332                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7333            let previous_snapshot = buffer_snapshots.last()?;
 7334
 7335            let build_incremental_change = || {
 7336                buffer
 7337                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7338                        previous_snapshot.snapshot.version(),
 7339                    )
 7340                    .map(|edit| {
 7341                        let edit_start = edit.new.start.0;
 7342                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7343                        let new_text = next_snapshot
 7344                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7345                            .collect();
 7346                        lsp::TextDocumentContentChangeEvent {
 7347                            range: Some(lsp::Range::new(
 7348                                point_to_lsp(edit_start),
 7349                                point_to_lsp(edit_end),
 7350                            )),
 7351                            range_length: None,
 7352                            text: new_text,
 7353                        }
 7354                    })
 7355                    .collect()
 7356            };
 7357
 7358            let document_sync_kind = language_server
 7359                .capabilities()
 7360                .text_document_sync
 7361                .as_ref()
 7362                .and_then(|sync| match sync {
 7363                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7364                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7365                });
 7366
 7367            let content_changes: Vec<_> = match document_sync_kind {
 7368                Some(lsp::TextDocumentSyncKind::FULL) => {
 7369                    vec![lsp::TextDocumentContentChangeEvent {
 7370                        range: None,
 7371                        range_length: None,
 7372                        text: next_snapshot.text(),
 7373                    }]
 7374                }
 7375                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7376                _ => {
 7377                    #[cfg(any(test, feature = "test-support"))]
 7378                    {
 7379                        build_incremental_change()
 7380                    }
 7381
 7382                    #[cfg(not(any(test, feature = "test-support")))]
 7383                    {
 7384                        continue;
 7385                    }
 7386                }
 7387            };
 7388
 7389            let next_version = previous_snapshot.version + 1;
 7390            buffer_snapshots.push(LspBufferSnapshot {
 7391                version: next_version,
 7392                snapshot: next_snapshot.clone(),
 7393            });
 7394
 7395            language_server
 7396                .notify::<lsp::notification::DidChangeTextDocument>(
 7397                    &lsp::DidChangeTextDocumentParams {
 7398                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7399                            uri.clone(),
 7400                            next_version,
 7401                        ),
 7402                        content_changes,
 7403                    },
 7404                )
 7405                .ok();
 7406            self.pull_workspace_diagnostics(language_server.server_id());
 7407        }
 7408
 7409        None
 7410    }
 7411
 7412    pub fn on_buffer_saved(
 7413        &mut self,
 7414        buffer: Entity<Buffer>,
 7415        cx: &mut Context<Self>,
 7416    ) -> Option<()> {
 7417        let file = File::from_dyn(buffer.read(cx).file())?;
 7418        let worktree_id = file.worktree_id(cx);
 7419        let abs_path = file.as_local()?.abs_path(cx);
 7420        let text_document = lsp::TextDocumentIdentifier {
 7421            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7422        };
 7423        let local = self.as_local()?;
 7424
 7425        for server in local.language_servers_for_worktree(worktree_id) {
 7426            if let Some(include_text) = include_text(server.as_ref()) {
 7427                let text = if include_text {
 7428                    Some(buffer.read(cx).text())
 7429                } else {
 7430                    None
 7431                };
 7432                server
 7433                    .notify::<lsp::notification::DidSaveTextDocument>(
 7434                        &lsp::DidSaveTextDocumentParams {
 7435                            text_document: text_document.clone(),
 7436                            text,
 7437                        },
 7438                    )
 7439                    .ok();
 7440            }
 7441        }
 7442
 7443        let language_servers = buffer.update(cx, |buffer, cx| {
 7444            local.language_server_ids_for_buffer(buffer, cx)
 7445        });
 7446        for language_server_id in language_servers {
 7447            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7448        }
 7449
 7450        None
 7451    }
 7452
 7453    async fn refresh_workspace_configurations(
 7454        lsp_store: &WeakEntity<Self>,
 7455        fs: Arc<dyn Fs>,
 7456        cx: &mut AsyncApp,
 7457    ) {
 7458        maybe!(async move {
 7459            let mut refreshed_servers = HashSet::default();
 7460            let servers = lsp_store
 7461                .update(cx, |lsp_store, cx| {
 7462                    let local = lsp_store.as_local()?;
 7463
 7464                    let servers = local
 7465                        .language_server_ids
 7466                        .iter()
 7467                        .filter_map(|(seed, state)| {
 7468                            let worktree = lsp_store
 7469                                .worktree_store
 7470                                .read(cx)
 7471                                .worktree_for_id(seed.worktree_id, cx);
 7472                            let delegate: Arc<dyn LspAdapterDelegate> =
 7473                                worktree.map(|worktree| {
 7474                                    LocalLspAdapterDelegate::new(
 7475                                        local.languages.clone(),
 7476                                        &local.environment,
 7477                                        cx.weak_entity(),
 7478                                        &worktree,
 7479                                        local.http_client.clone(),
 7480                                        local.fs.clone(),
 7481                                        cx,
 7482                                    )
 7483                                })?;
 7484                            let server_id = state.id;
 7485
 7486                            let states = local.language_servers.get(&server_id)?;
 7487
 7488                            match states {
 7489                                LanguageServerState::Starting { .. } => None,
 7490                                LanguageServerState::Running {
 7491                                    adapter, server, ..
 7492                                } => {
 7493                                    let fs = fs.clone();
 7494
 7495                                    let adapter = adapter.clone();
 7496                                    let server = server.clone();
 7497                                    refreshed_servers.insert(server.name());
 7498                                    let toolchain = seed.toolchain.clone();
 7499                                    Some(cx.spawn(async move |_, cx| {
 7500                                        let settings =
 7501                                            LocalLspStore::workspace_configuration_for_adapter(
 7502                                                adapter.adapter.clone(),
 7503                                                fs.as_ref(),
 7504                                                &delegate,
 7505                                                toolchain,
 7506                                                cx,
 7507                                            )
 7508                                            .await
 7509                                            .ok()?;
 7510                                        server
 7511                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7512                                                &lsp::DidChangeConfigurationParams { settings },
 7513                                            )
 7514                                            .ok()?;
 7515                                        Some(())
 7516                                    }))
 7517                                }
 7518                            }
 7519                        })
 7520                        .collect::<Vec<_>>();
 7521
 7522                    Some(servers)
 7523                })
 7524                .ok()
 7525                .flatten()?;
 7526
 7527            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7528            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7529            // to stop and unregister its language server wrapper.
 7530            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7531            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7532            let _: Vec<Option<()>> = join_all(servers).await;
 7533
 7534            Some(())
 7535        })
 7536        .await;
 7537    }
 7538
 7539    fn maintain_workspace_config(
 7540        fs: Arc<dyn Fs>,
 7541        external_refresh_requests: watch::Receiver<()>,
 7542        cx: &mut Context<Self>,
 7543    ) -> Task<Result<()>> {
 7544        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7545        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7546
 7547        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7548            *settings_changed_tx.borrow_mut() = ();
 7549        });
 7550
 7551        let mut joint_future =
 7552            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7553        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7554        // - 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).
 7555        // - 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.
 7556        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7557        // - 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,
 7558        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7559        cx.spawn(async move |this, cx| {
 7560            while let Some(()) = joint_future.next().await {
 7561                this.update(cx, |this, cx| {
 7562                    this.refresh_server_tree(cx);
 7563                })
 7564                .ok();
 7565
 7566                Self::refresh_workspace_configurations(&this, fs.clone(), cx).await;
 7567            }
 7568
 7569            drop(settings_observation);
 7570            anyhow::Ok(())
 7571        })
 7572    }
 7573
 7574    pub fn language_servers_for_local_buffer<'a>(
 7575        &'a self,
 7576        buffer: &Buffer,
 7577        cx: &mut App,
 7578    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7579        let local = self.as_local();
 7580        let language_server_ids = local
 7581            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7582            .unwrap_or_default();
 7583
 7584        language_server_ids
 7585            .into_iter()
 7586            .filter_map(
 7587                move |server_id| match local?.language_servers.get(&server_id)? {
 7588                    LanguageServerState::Running {
 7589                        adapter, server, ..
 7590                    } => Some((adapter, server)),
 7591                    _ => None,
 7592                },
 7593            )
 7594    }
 7595
 7596    pub fn language_server_for_local_buffer<'a>(
 7597        &'a self,
 7598        buffer: &'a Buffer,
 7599        server_id: LanguageServerId,
 7600        cx: &'a mut App,
 7601    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7602        self.as_local()?
 7603            .language_servers_for_buffer(buffer, cx)
 7604            .find(|(_, s)| s.server_id() == server_id)
 7605    }
 7606
 7607    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7608        self.diagnostic_summaries.remove(&id_to_remove);
 7609        if let Some(local) = self.as_local_mut() {
 7610            let to_remove = local.remove_worktree(id_to_remove, cx);
 7611            for server in to_remove {
 7612                self.language_server_statuses.remove(&server);
 7613            }
 7614        }
 7615    }
 7616
 7617    pub fn shared(
 7618        &mut self,
 7619        project_id: u64,
 7620        downstream_client: AnyProtoClient,
 7621        _: &mut Context<Self>,
 7622    ) {
 7623        self.downstream_client = Some((downstream_client.clone(), project_id));
 7624
 7625        for (server_id, status) in &self.language_server_statuses {
 7626            if let Some(server) = self.language_server_for_id(*server_id) {
 7627                downstream_client
 7628                    .send(proto::StartLanguageServer {
 7629                        project_id,
 7630                        server: Some(proto::LanguageServer {
 7631                            id: server_id.to_proto(),
 7632                            name: status.name.to_string(),
 7633                            worktree_id: None,
 7634                        }),
 7635                        capabilities: serde_json::to_string(&server.capabilities())
 7636                            .expect("serializing server LSP capabilities"),
 7637                    })
 7638                    .log_err();
 7639            }
 7640        }
 7641    }
 7642
 7643    pub fn disconnected_from_host(&mut self) {
 7644        self.downstream_client.take();
 7645    }
 7646
 7647    pub fn disconnected_from_ssh_remote(&mut self) {
 7648        if let LspStoreMode::Remote(RemoteLspStore {
 7649            upstream_client, ..
 7650        }) = &mut self.mode
 7651        {
 7652            upstream_client.take();
 7653        }
 7654    }
 7655
 7656    pub(crate) fn set_language_server_statuses_from_proto(
 7657        &mut self,
 7658        language_servers: Vec<proto::LanguageServer>,
 7659        server_capabilities: Vec<String>,
 7660    ) {
 7661        self.language_server_statuses = language_servers
 7662            .into_iter()
 7663            .zip(server_capabilities)
 7664            .map(|(server, server_capabilities)| {
 7665                let server_id = LanguageServerId(server.id as usize);
 7666                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7667                    self.lsp_server_capabilities
 7668                        .insert(server_id, server_capabilities);
 7669                }
 7670                (
 7671                    server_id,
 7672                    LanguageServerStatus {
 7673                        name: LanguageServerName::from_proto(server.name),
 7674                        pending_work: Default::default(),
 7675                        has_pending_diagnostic_updates: false,
 7676                        progress_tokens: Default::default(),
 7677                    },
 7678                )
 7679            })
 7680            .collect();
 7681    }
 7682
 7683    #[cfg(test)]
 7684    pub fn update_diagnostic_entries(
 7685        &mut self,
 7686        server_id: LanguageServerId,
 7687        abs_path: PathBuf,
 7688        result_id: Option<String>,
 7689        version: Option<i32>,
 7690        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7691        cx: &mut Context<Self>,
 7692    ) -> anyhow::Result<()> {
 7693        self.merge_diagnostic_entries(
 7694            vec![DocumentDiagnosticsUpdate {
 7695                diagnostics: DocumentDiagnostics {
 7696                    diagnostics,
 7697                    document_abs_path: abs_path,
 7698                    version,
 7699                },
 7700                result_id,
 7701                server_id,
 7702                disk_based_sources: Cow::Borrowed(&[]),
 7703            }],
 7704            |_, _, _| false,
 7705            cx,
 7706        )?;
 7707        Ok(())
 7708    }
 7709
 7710    pub fn merge_diagnostic_entries<'a>(
 7711        &mut self,
 7712        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7713        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7714        cx: &mut Context<Self>,
 7715    ) -> anyhow::Result<()> {
 7716        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7717        let mut updated_diagnostics_paths = HashMap::default();
 7718        for mut update in diagnostic_updates {
 7719            let abs_path = &update.diagnostics.document_abs_path;
 7720            let server_id = update.server_id;
 7721            let Some((worktree, relative_path)) =
 7722                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7723            else {
 7724                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7725                return Ok(());
 7726            };
 7727
 7728            let worktree_id = worktree.read(cx).id();
 7729            let project_path = ProjectPath {
 7730                worktree_id,
 7731                path: relative_path.into(),
 7732            };
 7733
 7734            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7735                let snapshot = buffer_handle.read(cx).snapshot();
 7736                let buffer = buffer_handle.read(cx);
 7737                let reused_diagnostics = buffer
 7738                    .get_diagnostics(server_id)
 7739                    .into_iter()
 7740                    .flat_map(|diag| {
 7741                        diag.iter()
 7742                            .filter(|v| merge(buffer, &v.diagnostic, cx))
 7743                            .map(|v| {
 7744                                let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7745                                let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7746                                DiagnosticEntry {
 7747                                    range: start..end,
 7748                                    diagnostic: v.diagnostic.clone(),
 7749                                }
 7750                            })
 7751                    })
 7752                    .collect::<Vec<_>>();
 7753
 7754                self.as_local_mut()
 7755                    .context("cannot merge diagnostics on a remote LspStore")?
 7756                    .update_buffer_diagnostics(
 7757                        &buffer_handle,
 7758                        server_id,
 7759                        update.result_id,
 7760                        update.diagnostics.version,
 7761                        update.diagnostics.diagnostics.clone(),
 7762                        reused_diagnostics.clone(),
 7763                        cx,
 7764                    )?;
 7765
 7766                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7767            }
 7768
 7769            let updated = worktree.update(cx, |worktree, cx| {
 7770                self.update_worktree_diagnostics(
 7771                    worktree.id(),
 7772                    server_id,
 7773                    project_path.path.clone(),
 7774                    update.diagnostics.diagnostics,
 7775                    cx,
 7776                )
 7777            })?;
 7778            match updated {
 7779                ControlFlow::Continue(new_summary) => {
 7780                    if let Some((project_id, new_summary)) = new_summary {
 7781                        match &mut diagnostics_summary {
 7782                            Some(diagnostics_summary) => {
 7783                                diagnostics_summary
 7784                                    .more_summaries
 7785                                    .push(proto::DiagnosticSummary {
 7786                                        path: project_path.path.as_ref().to_proto(),
 7787                                        language_server_id: server_id.0 as u64,
 7788                                        error_count: new_summary.error_count,
 7789                                        warning_count: new_summary.warning_count,
 7790                                    })
 7791                            }
 7792                            None => {
 7793                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7794                                    project_id,
 7795                                    worktree_id: worktree_id.to_proto(),
 7796                                    summary: Some(proto::DiagnosticSummary {
 7797                                        path: project_path.path.as_ref().to_proto(),
 7798                                        language_server_id: server_id.0 as u64,
 7799                                        error_count: new_summary.error_count,
 7800                                        warning_count: new_summary.warning_count,
 7801                                    }),
 7802                                    more_summaries: Vec::new(),
 7803                                })
 7804                            }
 7805                        }
 7806                    }
 7807                    updated_diagnostics_paths
 7808                        .entry(server_id)
 7809                        .or_insert_with(Vec::new)
 7810                        .push(project_path);
 7811                }
 7812                ControlFlow::Break(()) => {}
 7813            }
 7814        }
 7815
 7816        if let Some((diagnostics_summary, (downstream_client, _))) =
 7817            diagnostics_summary.zip(self.downstream_client.as_ref())
 7818        {
 7819            downstream_client.send(diagnostics_summary).log_err();
 7820        }
 7821        for (server_id, paths) in updated_diagnostics_paths {
 7822            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7823        }
 7824        Ok(())
 7825    }
 7826
 7827    fn update_worktree_diagnostics(
 7828        &mut self,
 7829        worktree_id: WorktreeId,
 7830        server_id: LanguageServerId,
 7831        path_in_worktree: Arc<Path>,
 7832        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7833        _: &mut Context<Worktree>,
 7834    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7835        let local = match &mut self.mode {
 7836            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7837            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7838        };
 7839
 7840        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7841        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7842        let summaries_by_server_id = summaries_for_tree
 7843            .entry(path_in_worktree.clone())
 7844            .or_default();
 7845
 7846        let old_summary = summaries_by_server_id
 7847            .remove(&server_id)
 7848            .unwrap_or_default();
 7849
 7850        let new_summary = DiagnosticSummary::new(&diagnostics);
 7851        if new_summary.is_empty() {
 7852            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7853            {
 7854                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7855                    diagnostics_by_server_id.remove(ix);
 7856                }
 7857                if diagnostics_by_server_id.is_empty() {
 7858                    diagnostics_for_tree.remove(&path_in_worktree);
 7859                }
 7860            }
 7861        } else {
 7862            summaries_by_server_id.insert(server_id, new_summary);
 7863            let diagnostics_by_server_id = diagnostics_for_tree
 7864                .entry(path_in_worktree.clone())
 7865                .or_default();
 7866            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7867                Ok(ix) => {
 7868                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7869                }
 7870                Err(ix) => {
 7871                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7872                }
 7873            }
 7874        }
 7875
 7876        if !old_summary.is_empty() || !new_summary.is_empty() {
 7877            if let Some((_, project_id)) = &self.downstream_client {
 7878                Ok(ControlFlow::Continue(Some((
 7879                    *project_id,
 7880                    proto::DiagnosticSummary {
 7881                        path: path_in_worktree.to_proto(),
 7882                        language_server_id: server_id.0 as u64,
 7883                        error_count: new_summary.error_count as u32,
 7884                        warning_count: new_summary.warning_count as u32,
 7885                    },
 7886                ))))
 7887            } else {
 7888                Ok(ControlFlow::Continue(None))
 7889            }
 7890        } else {
 7891            Ok(ControlFlow::Break(()))
 7892        }
 7893    }
 7894
 7895    pub fn open_buffer_for_symbol(
 7896        &mut self,
 7897        symbol: &Symbol,
 7898        cx: &mut Context<Self>,
 7899    ) -> Task<Result<Entity<Buffer>>> {
 7900        if let Some((client, project_id)) = self.upstream_client() {
 7901            let request = client.request(proto::OpenBufferForSymbol {
 7902                project_id,
 7903                symbol: Some(Self::serialize_symbol(symbol)),
 7904            });
 7905            cx.spawn(async move |this, cx| {
 7906                let response = request.await?;
 7907                let buffer_id = BufferId::new(response.buffer_id)?;
 7908                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7909                    .await
 7910            })
 7911        } else if let Some(local) = self.as_local() {
 7912            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7913                seed.worktree_id == symbol.source_worktree_id
 7914                    && state.id == symbol.source_language_server_id
 7915                    && symbol.language_server_name == seed.name
 7916            });
 7917            if !is_valid {
 7918                return Task::ready(Err(anyhow!(
 7919                    "language server for worktree and language not found"
 7920                )));
 7921            };
 7922
 7923            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7924                .worktree_store
 7925                .read(cx)
 7926                .worktree_for_id(symbol.path.worktree_id, cx)
 7927                .map(|worktree| worktree.read(cx).abs_path())
 7928            {
 7929                worktree_abs_path
 7930            } else {
 7931                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7932            };
 7933
 7934            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7935            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
 7936                uri
 7937            } else {
 7938                return Task::ready(Err(anyhow!("invalid symbol path")));
 7939            };
 7940
 7941            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7942        } else {
 7943            Task::ready(Err(anyhow!("no upstream client or local store")))
 7944        }
 7945    }
 7946
 7947    pub(crate) fn open_local_buffer_via_lsp(
 7948        &mut self,
 7949        mut abs_path: lsp::Url,
 7950        language_server_id: LanguageServerId,
 7951        cx: &mut Context<Self>,
 7952    ) -> Task<Result<Entity<Buffer>>> {
 7953        cx.spawn(async move |lsp_store, cx| {
 7954            // Escape percent-encoded string.
 7955            let current_scheme = abs_path.scheme().to_owned();
 7956            let _ = abs_path.set_scheme("file");
 7957
 7958            let abs_path = abs_path
 7959                .to_file_path()
 7960                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7961            let p = abs_path.clone();
 7962            let yarn_worktree = lsp_store
 7963                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7964                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7965                        cx.spawn(async move |this, cx| {
 7966                            let t = this
 7967                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7968                                .ok()?;
 7969                            t.await
 7970                        })
 7971                    }),
 7972                    None => Task::ready(None),
 7973                })?
 7974                .await;
 7975            let (worktree_root_target, known_relative_path) =
 7976                if let Some((zip_root, relative_path)) = yarn_worktree {
 7977                    (zip_root, Some(relative_path))
 7978                } else {
 7979                    (Arc::<Path>::from(abs_path.as_path()), None)
 7980                };
 7981            let (worktree, relative_path) = if let Some(result) =
 7982                lsp_store.update(cx, |lsp_store, cx| {
 7983                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7984                        worktree_store.find_worktree(&worktree_root_target, cx)
 7985                    })
 7986                })? {
 7987                let relative_path =
 7988                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7989                (result.0, relative_path)
 7990            } else {
 7991                let worktree = lsp_store
 7992                    .update(cx, |lsp_store, cx| {
 7993                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7994                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7995                        })
 7996                    })?
 7997                    .await?;
 7998                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7999                    lsp_store
 8000                        .update(cx, |lsp_store, cx| {
 8001                            if let Some(local) = lsp_store.as_local_mut() {
 8002                                local.register_language_server_for_invisible_worktree(
 8003                                    &worktree,
 8004                                    language_server_id,
 8005                                    cx,
 8006                                )
 8007                            }
 8008                        })
 8009                        .ok();
 8010                }
 8011                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8012                let relative_path = if let Some(known_path) = known_relative_path {
 8013                    known_path
 8014                } else {
 8015                    abs_path.strip_prefix(worktree_root)?.into()
 8016                };
 8017                (worktree, relative_path)
 8018            };
 8019            let project_path = ProjectPath {
 8020                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8021                path: relative_path,
 8022            };
 8023            lsp_store
 8024                .update(cx, |lsp_store, cx| {
 8025                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8026                        buffer_store.open_buffer(project_path, cx)
 8027                    })
 8028                })?
 8029                .await
 8030        })
 8031    }
 8032
 8033    fn request_multiple_lsp_locally<P, R>(
 8034        &mut self,
 8035        buffer: &Entity<Buffer>,
 8036        position: Option<P>,
 8037        request: R,
 8038        cx: &mut Context<Self>,
 8039    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8040    where
 8041        P: ToOffset,
 8042        R: LspCommand + Clone,
 8043        <R::LspRequest as lsp::request::Request>::Result: Send,
 8044        <R::LspRequest as lsp::request::Request>::Params: Send,
 8045    {
 8046        let Some(local) = self.as_local() else {
 8047            return Task::ready(Vec::new());
 8048        };
 8049
 8050        let snapshot = buffer.read(cx).snapshot();
 8051        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8052
 8053        let server_ids = buffer.update(cx, |buffer, cx| {
 8054            local
 8055                .language_servers_for_buffer(buffer, cx)
 8056                .filter(|(adapter, _)| {
 8057                    scope
 8058                        .as_ref()
 8059                        .map(|scope| scope.language_allowed(&adapter.name))
 8060                        .unwrap_or(true)
 8061                })
 8062                .map(|(_, server)| server.server_id())
 8063                .filter(|server_id| {
 8064                    self.as_local().is_none_or(|local| {
 8065                        local
 8066                            .buffers_opened_in_servers
 8067                            .get(&snapshot.remote_id())
 8068                            .is_some_and(|servers| servers.contains(server_id))
 8069                    })
 8070                })
 8071                .collect::<Vec<_>>()
 8072        });
 8073
 8074        let mut response_results = server_ids
 8075            .into_iter()
 8076            .map(|server_id| {
 8077                let task = self.request_lsp(
 8078                    buffer.clone(),
 8079                    LanguageServerToQuery::Other(server_id),
 8080                    request.clone(),
 8081                    cx,
 8082                );
 8083                async move { (server_id, task.await) }
 8084            })
 8085            .collect::<FuturesUnordered<_>>();
 8086
 8087        cx.background_spawn(async move {
 8088            let mut responses = Vec::with_capacity(response_results.len());
 8089            while let Some((server_id, response_result)) = response_results.next().await {
 8090                if let Some(response) = response_result.log_err() {
 8091                    responses.push((server_id, response));
 8092                }
 8093            }
 8094            responses
 8095        })
 8096    }
 8097
 8098    async fn handle_lsp_command<T: LspCommand>(
 8099        this: Entity<Self>,
 8100        envelope: TypedEnvelope<T::ProtoRequest>,
 8101        mut cx: AsyncApp,
 8102    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8103    where
 8104        <T::LspRequest as lsp::request::Request>::Params: Send,
 8105        <T::LspRequest as lsp::request::Request>::Result: Send,
 8106    {
 8107        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8108        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8109        let buffer_handle = this.update(&mut cx, |this, cx| {
 8110            this.buffer_store.read(cx).get_existing(buffer_id)
 8111        })??;
 8112        let request = T::from_proto(
 8113            envelope.payload,
 8114            this.clone(),
 8115            buffer_handle.clone(),
 8116            cx.clone(),
 8117        )
 8118        .await?;
 8119        let response = this
 8120            .update(&mut cx, |this, cx| {
 8121                this.request_lsp(
 8122                    buffer_handle.clone(),
 8123                    LanguageServerToQuery::FirstCapable,
 8124                    request,
 8125                    cx,
 8126                )
 8127            })?
 8128            .await?;
 8129        this.update(&mut cx, |this, cx| {
 8130            Ok(T::response_to_proto(
 8131                response,
 8132                this,
 8133                sender_id,
 8134                &buffer_handle.read(cx).version(),
 8135                cx,
 8136            ))
 8137        })?
 8138    }
 8139
 8140    async fn handle_multi_lsp_query(
 8141        lsp_store: Entity<Self>,
 8142        envelope: TypedEnvelope<proto::MultiLspQuery>,
 8143        mut cx: AsyncApp,
 8144    ) -> Result<proto::MultiLspQueryResponse> {
 8145        let response_from_ssh = lsp_store.read_with(&cx, |this, _| {
 8146            let (upstream_client, project_id) = this.upstream_client()?;
 8147            let mut payload = envelope.payload.clone();
 8148            payload.project_id = project_id;
 8149
 8150            Some(upstream_client.request(payload))
 8151        })?;
 8152        if let Some(response_from_ssh) = response_from_ssh {
 8153            return response_from_ssh.await;
 8154        }
 8155
 8156        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8157        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8158        let version = deserialize_version(&envelope.payload.version);
 8159        let buffer = lsp_store.update(&mut cx, |this, cx| {
 8160            this.buffer_store.read(cx).get_existing(buffer_id)
 8161        })??;
 8162        buffer
 8163            .update(&mut cx, |buffer, _| {
 8164                buffer.wait_for_version(version.clone())
 8165            })?
 8166            .await?;
 8167        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
 8168        match envelope
 8169            .payload
 8170            .strategy
 8171            .context("invalid request without the strategy")?
 8172        {
 8173            proto::multi_lsp_query::Strategy::All(_) => {
 8174                // currently, there's only one multiple language servers query strategy,
 8175                // so just ensure it's specified correctly
 8176            }
 8177        }
 8178        match envelope.payload.request {
 8179            Some(proto::multi_lsp_query::Request::GetHover(message)) => {
 8180                buffer
 8181                    .update(&mut cx, |buffer, _| {
 8182                        buffer.wait_for_version(deserialize_version(&message.version))
 8183                    })?
 8184                    .await?;
 8185                let get_hover =
 8186                    GetHover::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8187                        .await?;
 8188                let all_hovers = lsp_store
 8189                    .update(&mut cx, |this, cx| {
 8190                        this.request_multiple_lsp_locally(
 8191                            &buffer,
 8192                            Some(get_hover.position),
 8193                            get_hover,
 8194                            cx,
 8195                        )
 8196                    })?
 8197                    .await
 8198                    .into_iter()
 8199                    .filter_map(|(server_id, hover)| {
 8200                        Some((server_id, remove_empty_hover_blocks(hover?)?))
 8201                    });
 8202                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8203                    responses: all_hovers
 8204                        .map(|(server_id, hover)| proto::LspResponse {
 8205                            server_id: server_id.to_proto(),
 8206                            response: Some(proto::lsp_response::Response::GetHoverResponse(
 8207                                GetHover::response_to_proto(
 8208                                    Some(hover),
 8209                                    project,
 8210                                    sender_id,
 8211                                    &buffer_version,
 8212                                    cx,
 8213                                ),
 8214                            )),
 8215                        })
 8216                        .collect(),
 8217                })
 8218            }
 8219            Some(proto::multi_lsp_query::Request::GetCodeActions(message)) => {
 8220                buffer
 8221                    .update(&mut cx, |buffer, _| {
 8222                        buffer.wait_for_version(deserialize_version(&message.version))
 8223                    })?
 8224                    .await?;
 8225                let get_code_actions = GetCodeActions::from_proto(
 8226                    message,
 8227                    lsp_store.clone(),
 8228                    buffer.clone(),
 8229                    cx.clone(),
 8230                )
 8231                .await?;
 8232
 8233                let all_actions = lsp_store
 8234                    .update(&mut cx, |project, cx| {
 8235                        project.request_multiple_lsp_locally(
 8236                            &buffer,
 8237                            Some(get_code_actions.range.start),
 8238                            get_code_actions,
 8239                            cx,
 8240                        )
 8241                    })?
 8242                    .await
 8243                    .into_iter();
 8244
 8245                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8246                    responses: all_actions
 8247                        .map(|(server_id, code_actions)| proto::LspResponse {
 8248                            server_id: server_id.to_proto(),
 8249                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
 8250                                GetCodeActions::response_to_proto(
 8251                                    code_actions,
 8252                                    project,
 8253                                    sender_id,
 8254                                    &buffer_version,
 8255                                    cx,
 8256                                ),
 8257                            )),
 8258                        })
 8259                        .collect(),
 8260                })
 8261            }
 8262            Some(proto::multi_lsp_query::Request::GetSignatureHelp(message)) => {
 8263                buffer
 8264                    .update(&mut cx, |buffer, _| {
 8265                        buffer.wait_for_version(deserialize_version(&message.version))
 8266                    })?
 8267                    .await?;
 8268                let get_signature_help = GetSignatureHelp::from_proto(
 8269                    message,
 8270                    lsp_store.clone(),
 8271                    buffer.clone(),
 8272                    cx.clone(),
 8273                )
 8274                .await?;
 8275
 8276                let all_signatures = lsp_store
 8277                    .update(&mut cx, |project, cx| {
 8278                        project.request_multiple_lsp_locally(
 8279                            &buffer,
 8280                            Some(get_signature_help.position),
 8281                            get_signature_help,
 8282                            cx,
 8283                        )
 8284                    })?
 8285                    .await
 8286                    .into_iter();
 8287
 8288                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8289                    responses: all_signatures
 8290                        .map(|(server_id, signature_help)| proto::LspResponse {
 8291                            server_id: server_id.to_proto(),
 8292                            response: Some(
 8293                                proto::lsp_response::Response::GetSignatureHelpResponse(
 8294                                    GetSignatureHelp::response_to_proto(
 8295                                        signature_help,
 8296                                        project,
 8297                                        sender_id,
 8298                                        &buffer_version,
 8299                                        cx,
 8300                                    ),
 8301                                ),
 8302                            ),
 8303                        })
 8304                        .collect(),
 8305                })
 8306            }
 8307            Some(proto::multi_lsp_query::Request::GetCodeLens(message)) => {
 8308                buffer
 8309                    .update(&mut cx, |buffer, _| {
 8310                        buffer.wait_for_version(deserialize_version(&message.version))
 8311                    })?
 8312                    .await?;
 8313                let get_code_lens =
 8314                    GetCodeLens::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8315                        .await?;
 8316
 8317                let code_lens_actions = lsp_store
 8318                    .update(&mut cx, |project, cx| {
 8319                        project.request_multiple_lsp_locally(
 8320                            &buffer,
 8321                            None::<usize>,
 8322                            get_code_lens,
 8323                            cx,
 8324                        )
 8325                    })?
 8326                    .await
 8327                    .into_iter();
 8328
 8329                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8330                    responses: code_lens_actions
 8331                        .map(|(server_id, actions)| proto::LspResponse {
 8332                            server_id: server_id.to_proto(),
 8333                            response: Some(proto::lsp_response::Response::GetCodeLensResponse(
 8334                                GetCodeLens::response_to_proto(
 8335                                    actions,
 8336                                    project,
 8337                                    sender_id,
 8338                                    &buffer_version,
 8339                                    cx,
 8340                                ),
 8341                            )),
 8342                        })
 8343                        .collect(),
 8344                })
 8345            }
 8346            Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(message)) => {
 8347                buffer
 8348                    .update(&mut cx, |buffer, _| {
 8349                        buffer.wait_for_version(deserialize_version(&message.version))
 8350                    })?
 8351                    .await?;
 8352                lsp_store
 8353                    .update(&mut cx, |lsp_store, cx| {
 8354                        lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8355                    })?
 8356                    .await?;
 8357                // `pull_diagnostics_for_buffer` will merge in the new diagnostics and send them to the client.
 8358                // The client cannot merge anything into its non-local LspStore, so we do not need to return anything.
 8359                Ok(proto::MultiLspQueryResponse {
 8360                    responses: Vec::new(),
 8361                })
 8362            }
 8363            Some(proto::multi_lsp_query::Request::GetDocumentColor(message)) => {
 8364                buffer
 8365                    .update(&mut cx, |buffer, _| {
 8366                        buffer.wait_for_version(deserialize_version(&message.version))
 8367                    })?
 8368                    .await?;
 8369                let get_document_color = GetDocumentColor::from_proto(
 8370                    message,
 8371                    lsp_store.clone(),
 8372                    buffer.clone(),
 8373                    cx.clone(),
 8374                )
 8375                .await?;
 8376
 8377                let all_colors = lsp_store
 8378                    .update(&mut cx, |project, cx| {
 8379                        project.request_multiple_lsp_locally(
 8380                            &buffer,
 8381                            None::<usize>,
 8382                            get_document_color,
 8383                            cx,
 8384                        )
 8385                    })?
 8386                    .await
 8387                    .into_iter();
 8388
 8389                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8390                    responses: all_colors
 8391                        .map(|(server_id, colors)| proto::LspResponse {
 8392                            server_id: server_id.to_proto(),
 8393                            response: Some(
 8394                                proto::lsp_response::Response::GetDocumentColorResponse(
 8395                                    GetDocumentColor::response_to_proto(
 8396                                        colors,
 8397                                        project,
 8398                                        sender_id,
 8399                                        &buffer_version,
 8400                                        cx,
 8401                                    ),
 8402                                ),
 8403                            ),
 8404                        })
 8405                        .collect(),
 8406                })
 8407            }
 8408            Some(proto::multi_lsp_query::Request::GetDefinition(message)) => {
 8409                let get_definitions = GetDefinitions::from_proto(
 8410                    message,
 8411                    lsp_store.clone(),
 8412                    buffer.clone(),
 8413                    cx.clone(),
 8414                )
 8415                .await?;
 8416
 8417                let definitions = lsp_store
 8418                    .update(&mut cx, |project, cx| {
 8419                        project.request_multiple_lsp_locally(
 8420                            &buffer,
 8421                            Some(get_definitions.position),
 8422                            get_definitions,
 8423                            cx,
 8424                        )
 8425                    })?
 8426                    .await
 8427                    .into_iter();
 8428
 8429                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8430                    responses: definitions
 8431                        .map(|(server_id, definitions)| proto::LspResponse {
 8432                            server_id: server_id.to_proto(),
 8433                            response: Some(proto::lsp_response::Response::GetDefinitionResponse(
 8434                                GetDefinitions::response_to_proto(
 8435                                    definitions,
 8436                                    project,
 8437                                    sender_id,
 8438                                    &buffer_version,
 8439                                    cx,
 8440                                ),
 8441                            )),
 8442                        })
 8443                        .collect(),
 8444                })
 8445            }
 8446            Some(proto::multi_lsp_query::Request::GetDeclaration(message)) => {
 8447                let get_declarations = GetDeclarations::from_proto(
 8448                    message,
 8449                    lsp_store.clone(),
 8450                    buffer.clone(),
 8451                    cx.clone(),
 8452                )
 8453                .await?;
 8454
 8455                let declarations = lsp_store
 8456                    .update(&mut cx, |project, cx| {
 8457                        project.request_multiple_lsp_locally(
 8458                            &buffer,
 8459                            Some(get_declarations.position),
 8460                            get_declarations,
 8461                            cx,
 8462                        )
 8463                    })?
 8464                    .await
 8465                    .into_iter();
 8466
 8467                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8468                    responses: declarations
 8469                        .map(|(server_id, declarations)| proto::LspResponse {
 8470                            server_id: server_id.to_proto(),
 8471                            response: Some(proto::lsp_response::Response::GetDeclarationResponse(
 8472                                GetDeclarations::response_to_proto(
 8473                                    declarations,
 8474                                    project,
 8475                                    sender_id,
 8476                                    &buffer_version,
 8477                                    cx,
 8478                                ),
 8479                            )),
 8480                        })
 8481                        .collect(),
 8482                })
 8483            }
 8484            Some(proto::multi_lsp_query::Request::GetTypeDefinition(message)) => {
 8485                let get_type_definitions = GetTypeDefinitions::from_proto(
 8486                    message,
 8487                    lsp_store.clone(),
 8488                    buffer.clone(),
 8489                    cx.clone(),
 8490                )
 8491                .await?;
 8492
 8493                let type_definitions = lsp_store
 8494                    .update(&mut cx, |project, cx| {
 8495                        project.request_multiple_lsp_locally(
 8496                            &buffer,
 8497                            Some(get_type_definitions.position),
 8498                            get_type_definitions,
 8499                            cx,
 8500                        )
 8501                    })?
 8502                    .await
 8503                    .into_iter();
 8504
 8505                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8506                    responses: type_definitions
 8507                        .map(|(server_id, type_definitions)| proto::LspResponse {
 8508                            server_id: server_id.to_proto(),
 8509                            response: Some(
 8510                                proto::lsp_response::Response::GetTypeDefinitionResponse(
 8511                                    GetTypeDefinitions::response_to_proto(
 8512                                        type_definitions,
 8513                                        project,
 8514                                        sender_id,
 8515                                        &buffer_version,
 8516                                        cx,
 8517                                    ),
 8518                                ),
 8519                            ),
 8520                        })
 8521                        .collect(),
 8522                })
 8523            }
 8524            Some(proto::multi_lsp_query::Request::GetImplementation(message)) => {
 8525                let get_implementations = GetImplementations::from_proto(
 8526                    message,
 8527                    lsp_store.clone(),
 8528                    buffer.clone(),
 8529                    cx.clone(),
 8530                )
 8531                .await?;
 8532
 8533                let implementations = lsp_store
 8534                    .update(&mut cx, |project, cx| {
 8535                        project.request_multiple_lsp_locally(
 8536                            &buffer,
 8537                            Some(get_implementations.position),
 8538                            get_implementations,
 8539                            cx,
 8540                        )
 8541                    })?
 8542                    .await
 8543                    .into_iter();
 8544
 8545                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8546                    responses: implementations
 8547                        .map(|(server_id, implementations)| proto::LspResponse {
 8548                            server_id: server_id.to_proto(),
 8549                            response: Some(
 8550                                proto::lsp_response::Response::GetImplementationResponse(
 8551                                    GetImplementations::response_to_proto(
 8552                                        implementations,
 8553                                        project,
 8554                                        sender_id,
 8555                                        &buffer_version,
 8556                                        cx,
 8557                                    ),
 8558                                ),
 8559                            ),
 8560                        })
 8561                        .collect(),
 8562                })
 8563            }
 8564            Some(proto::multi_lsp_query::Request::GetReferences(message)) => {
 8565                let get_references = GetReferences::from_proto(
 8566                    message,
 8567                    lsp_store.clone(),
 8568                    buffer.clone(),
 8569                    cx.clone(),
 8570                )
 8571                .await?;
 8572
 8573                let references = lsp_store
 8574                    .update(&mut cx, |project, cx| {
 8575                        project.request_multiple_lsp_locally(
 8576                            &buffer,
 8577                            Some(get_references.position),
 8578                            get_references,
 8579                            cx,
 8580                        )
 8581                    })?
 8582                    .await
 8583                    .into_iter();
 8584
 8585                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8586                    responses: references
 8587                        .map(|(server_id, references)| proto::LspResponse {
 8588                            server_id: server_id.to_proto(),
 8589                            response: Some(proto::lsp_response::Response::GetReferencesResponse(
 8590                                GetReferences::response_to_proto(
 8591                                    references,
 8592                                    project,
 8593                                    sender_id,
 8594                                    &buffer_version,
 8595                                    cx,
 8596                                ),
 8597                            )),
 8598                        })
 8599                        .collect(),
 8600                })
 8601            }
 8602            None => anyhow::bail!("empty multi lsp query request"),
 8603        }
 8604    }
 8605
 8606    async fn handle_apply_code_action(
 8607        this: Entity<Self>,
 8608        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8609        mut cx: AsyncApp,
 8610    ) -> Result<proto::ApplyCodeActionResponse> {
 8611        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8612        let action =
 8613            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8614        let apply_code_action = this.update(&mut cx, |this, cx| {
 8615            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8616            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8617            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8618        })??;
 8619
 8620        let project_transaction = apply_code_action.await?;
 8621        let project_transaction = this.update(&mut cx, |this, cx| {
 8622            this.buffer_store.update(cx, |buffer_store, cx| {
 8623                buffer_store.serialize_project_transaction_for_peer(
 8624                    project_transaction,
 8625                    sender_id,
 8626                    cx,
 8627                )
 8628            })
 8629        })?;
 8630        Ok(proto::ApplyCodeActionResponse {
 8631            transaction: Some(project_transaction),
 8632        })
 8633    }
 8634
 8635    async fn handle_register_buffer_with_language_servers(
 8636        this: Entity<Self>,
 8637        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8638        mut cx: AsyncApp,
 8639    ) -> Result<proto::Ack> {
 8640        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8641        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8642        this.update(&mut cx, |this, cx| {
 8643            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8644                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8645                    project_id: upstream_project_id,
 8646                    buffer_id: buffer_id.to_proto(),
 8647                    only_servers: envelope.payload.only_servers,
 8648                });
 8649            }
 8650
 8651            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8652                anyhow::bail!("buffer is not open");
 8653            };
 8654
 8655            let handle = this.register_buffer_with_language_servers(
 8656                &buffer,
 8657                envelope
 8658                    .payload
 8659                    .only_servers
 8660                    .into_iter()
 8661                    .filter_map(|selector| {
 8662                        Some(match selector.selector? {
 8663                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8664                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8665                            }
 8666                            proto::language_server_selector::Selector::Name(name) => {
 8667                                LanguageServerSelector::Name(LanguageServerName(
 8668                                    SharedString::from(name),
 8669                                ))
 8670                            }
 8671                        })
 8672                    })
 8673                    .collect(),
 8674                false,
 8675                cx,
 8676            );
 8677            this.buffer_store().update(cx, |buffer_store, _| {
 8678                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8679            });
 8680
 8681            Ok(())
 8682        })??;
 8683        Ok(proto::Ack {})
 8684    }
 8685
 8686    async fn handle_rename_project_entry(
 8687        this: Entity<Self>,
 8688        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8689        mut cx: AsyncApp,
 8690    ) -> Result<proto::ProjectEntryResponse> {
 8691        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8692        let (worktree_id, worktree, old_path, is_dir) = this
 8693            .update(&mut cx, |this, cx| {
 8694                this.worktree_store
 8695                    .read(cx)
 8696                    .worktree_and_entry_for_id(entry_id, cx)
 8697                    .map(|(worktree, entry)| {
 8698                        (
 8699                            worktree.read(cx).id(),
 8700                            worktree,
 8701                            entry.path.clone(),
 8702                            entry.is_dir(),
 8703                        )
 8704                    })
 8705            })?
 8706            .context("worktree not found")?;
 8707        let (old_abs_path, new_abs_path) = {
 8708            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8709            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8710            (root_path.join(&old_path), root_path.join(&new_path))
 8711        };
 8712
 8713        Self::will_rename_entry(
 8714            this.downgrade(),
 8715            worktree_id,
 8716            &old_abs_path,
 8717            &new_abs_path,
 8718            is_dir,
 8719            cx.clone(),
 8720        )
 8721        .await;
 8722        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8723        this.read_with(&cx, |this, _| {
 8724            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8725        })
 8726        .ok();
 8727        response
 8728    }
 8729
 8730    async fn handle_update_diagnostic_summary(
 8731        this: Entity<Self>,
 8732        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8733        mut cx: AsyncApp,
 8734    ) -> Result<()> {
 8735        this.update(&mut cx, |lsp_store, cx| {
 8736            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8737            let mut updated_diagnostics_paths = HashMap::default();
 8738            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8739            for message_summary in envelope
 8740                .payload
 8741                .summary
 8742                .into_iter()
 8743                .chain(envelope.payload.more_summaries)
 8744            {
 8745                let project_path = ProjectPath {
 8746                    worktree_id,
 8747                    path: Arc::<Path>::from_proto(message_summary.path),
 8748                };
 8749                let path = project_path.path.clone();
 8750                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8751                let summary = DiagnosticSummary {
 8752                    error_count: message_summary.error_count as usize,
 8753                    warning_count: message_summary.warning_count as usize,
 8754                };
 8755
 8756                if summary.is_empty() {
 8757                    if let Some(worktree_summaries) =
 8758                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8759                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8760                    {
 8761                        summaries.remove(&server_id);
 8762                        if summaries.is_empty() {
 8763                            worktree_summaries.remove(&path);
 8764                        }
 8765                    }
 8766                } else {
 8767                    lsp_store
 8768                        .diagnostic_summaries
 8769                        .entry(worktree_id)
 8770                        .or_default()
 8771                        .entry(path)
 8772                        .or_default()
 8773                        .insert(server_id, summary);
 8774                }
 8775
 8776                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8777                    match &mut diagnostics_summary {
 8778                        Some(diagnostics_summary) => {
 8779                            diagnostics_summary
 8780                                .more_summaries
 8781                                .push(proto::DiagnosticSummary {
 8782                                    path: project_path.path.as_ref().to_proto(),
 8783                                    language_server_id: server_id.0 as u64,
 8784                                    error_count: summary.error_count as u32,
 8785                                    warning_count: summary.warning_count as u32,
 8786                                })
 8787                        }
 8788                        None => {
 8789                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8790                                project_id: *project_id,
 8791                                worktree_id: worktree_id.to_proto(),
 8792                                summary: Some(proto::DiagnosticSummary {
 8793                                    path: project_path.path.as_ref().to_proto(),
 8794                                    language_server_id: server_id.0 as u64,
 8795                                    error_count: summary.error_count as u32,
 8796                                    warning_count: summary.warning_count as u32,
 8797                                }),
 8798                                more_summaries: Vec::new(),
 8799                            })
 8800                        }
 8801                    }
 8802                }
 8803                updated_diagnostics_paths
 8804                    .entry(server_id)
 8805                    .or_insert_with(Vec::new)
 8806                    .push(project_path);
 8807            }
 8808
 8809            if let Some((diagnostics_summary, (downstream_client, _))) =
 8810                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8811            {
 8812                downstream_client.send(diagnostics_summary).log_err();
 8813            }
 8814            for (server_id, paths) in updated_diagnostics_paths {
 8815                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8816            }
 8817            Ok(())
 8818        })?
 8819    }
 8820
 8821    async fn handle_start_language_server(
 8822        lsp_store: Entity<Self>,
 8823        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8824        mut cx: AsyncApp,
 8825    ) -> Result<()> {
 8826        let server = envelope.payload.server.context("invalid server")?;
 8827        let server_capabilities =
 8828            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8829                .with_context(|| {
 8830                    format!(
 8831                        "incorrect server capabilities {}",
 8832                        envelope.payload.capabilities
 8833                    )
 8834                })?;
 8835        lsp_store.update(&mut cx, |lsp_store, cx| {
 8836            let server_id = LanguageServerId(server.id as usize);
 8837            let server_name = LanguageServerName::from_proto(server.name.clone());
 8838            lsp_store
 8839                .lsp_server_capabilities
 8840                .insert(server_id, server_capabilities);
 8841            lsp_store.language_server_statuses.insert(
 8842                server_id,
 8843                LanguageServerStatus {
 8844                    name: server_name.clone(),
 8845                    pending_work: Default::default(),
 8846                    has_pending_diagnostic_updates: false,
 8847                    progress_tokens: Default::default(),
 8848                },
 8849            );
 8850            cx.emit(LspStoreEvent::LanguageServerAdded(
 8851                server_id,
 8852                server_name,
 8853                server.worktree_id.map(WorktreeId::from_proto),
 8854            ));
 8855            cx.notify();
 8856        })?;
 8857        Ok(())
 8858    }
 8859
 8860    async fn handle_update_language_server(
 8861        lsp_store: Entity<Self>,
 8862        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8863        mut cx: AsyncApp,
 8864    ) -> Result<()> {
 8865        lsp_store.update(&mut cx, |lsp_store, cx| {
 8866            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8867
 8868            match envelope.payload.variant.context("invalid variant")? {
 8869                proto::update_language_server::Variant::WorkStart(payload) => {
 8870                    lsp_store.on_lsp_work_start(
 8871                        language_server_id,
 8872                        payload.token,
 8873                        LanguageServerProgress {
 8874                            title: payload.title,
 8875                            is_disk_based_diagnostics_progress: false,
 8876                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8877                            message: payload.message,
 8878                            percentage: payload.percentage.map(|p| p as usize),
 8879                            last_update_at: cx.background_executor().now(),
 8880                        },
 8881                        cx,
 8882                    );
 8883                }
 8884                proto::update_language_server::Variant::WorkProgress(payload) => {
 8885                    lsp_store.on_lsp_work_progress(
 8886                        language_server_id,
 8887                        payload.token,
 8888                        LanguageServerProgress {
 8889                            title: None,
 8890                            is_disk_based_diagnostics_progress: false,
 8891                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8892                            message: payload.message,
 8893                            percentage: payload.percentage.map(|p| p as usize),
 8894                            last_update_at: cx.background_executor().now(),
 8895                        },
 8896                        cx,
 8897                    );
 8898                }
 8899
 8900                proto::update_language_server::Variant::WorkEnd(payload) => {
 8901                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8902                }
 8903
 8904                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8905                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8906                }
 8907
 8908                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8909                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8910                }
 8911
 8912                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8913                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8914                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8915                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8916                        language_server_id,
 8917                        name: envelope
 8918                            .payload
 8919                            .server_name
 8920                            .map(SharedString::new)
 8921                            .map(LanguageServerName),
 8922                        message: non_lsp,
 8923                    });
 8924                }
 8925            }
 8926
 8927            Ok(())
 8928        })?
 8929    }
 8930
 8931    async fn handle_language_server_log(
 8932        this: Entity<Self>,
 8933        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8934        mut cx: AsyncApp,
 8935    ) -> Result<()> {
 8936        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8937        let log_type = envelope
 8938            .payload
 8939            .log_type
 8940            .map(LanguageServerLogType::from_proto)
 8941            .context("invalid language server log type")?;
 8942
 8943        let message = envelope.payload.message;
 8944
 8945        this.update(&mut cx, |_, cx| {
 8946            cx.emit(LspStoreEvent::LanguageServerLog(
 8947                language_server_id,
 8948                log_type,
 8949                message,
 8950            ));
 8951        })
 8952    }
 8953
 8954    async fn handle_lsp_ext_cancel_flycheck(
 8955        lsp_store: Entity<Self>,
 8956        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 8957        cx: AsyncApp,
 8958    ) -> Result<proto::Ack> {
 8959        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8960        lsp_store.read_with(&cx, |lsp_store, _| {
 8961            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8962                server
 8963                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 8964                    .context("handling lsp ext cancel flycheck")
 8965            } else {
 8966                anyhow::Ok(())
 8967            }
 8968        })??;
 8969
 8970        Ok(proto::Ack {})
 8971    }
 8972
 8973    async fn handle_lsp_ext_run_flycheck(
 8974        lsp_store: Entity<Self>,
 8975        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 8976        mut cx: AsyncApp,
 8977    ) -> Result<proto::Ack> {
 8978        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8979        lsp_store.update(&mut cx, |lsp_store, cx| {
 8980            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8981                let text_document = if envelope.payload.current_file_only {
 8982                    let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8983                    lsp_store
 8984                        .buffer_store()
 8985                        .read(cx)
 8986                        .get(buffer_id)
 8987                        .and_then(|buffer| Some(buffer.read(cx).file()?.as_local()?.abs_path(cx)))
 8988                        .map(|path| make_text_document_identifier(&path))
 8989                        .transpose()?
 8990                } else {
 8991                    None
 8992                };
 8993                server
 8994                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 8995                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 8996                    )
 8997                    .context("handling lsp ext run flycheck")
 8998            } else {
 8999                anyhow::Ok(())
 9000            }
 9001        })??;
 9002
 9003        Ok(proto::Ack {})
 9004    }
 9005
 9006    async fn handle_lsp_ext_clear_flycheck(
 9007        lsp_store: Entity<Self>,
 9008        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9009        cx: AsyncApp,
 9010    ) -> Result<proto::Ack> {
 9011        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9012        lsp_store.read_with(&cx, |lsp_store, _| {
 9013            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9014                server
 9015                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 9016                    .context("handling lsp ext clear flycheck")
 9017            } else {
 9018                anyhow::Ok(())
 9019            }
 9020        })??;
 9021
 9022        Ok(proto::Ack {})
 9023    }
 9024
 9025    pub fn disk_based_diagnostics_started(
 9026        &mut self,
 9027        language_server_id: LanguageServerId,
 9028        cx: &mut Context<Self>,
 9029    ) {
 9030        if let Some(language_server_status) =
 9031            self.language_server_statuses.get_mut(&language_server_id)
 9032        {
 9033            language_server_status.has_pending_diagnostic_updates = true;
 9034        }
 9035
 9036        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9037        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9038            language_server_id,
 9039            name: self
 9040                .language_server_adapter_for_id(language_server_id)
 9041                .map(|adapter| adapter.name()),
 9042            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9043                Default::default(),
 9044            ),
 9045        })
 9046    }
 9047
 9048    pub fn disk_based_diagnostics_finished(
 9049        &mut self,
 9050        language_server_id: LanguageServerId,
 9051        cx: &mut Context<Self>,
 9052    ) {
 9053        if let Some(language_server_status) =
 9054            self.language_server_statuses.get_mut(&language_server_id)
 9055        {
 9056            language_server_status.has_pending_diagnostic_updates = false;
 9057        }
 9058
 9059        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9060        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9061            language_server_id,
 9062            name: self
 9063                .language_server_adapter_for_id(language_server_id)
 9064                .map(|adapter| adapter.name()),
 9065            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9066                Default::default(),
 9067            ),
 9068        })
 9069    }
 9070
 9071    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9072    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9073    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9074    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9075    // the language server might take some time to publish diagnostics.
 9076    fn simulate_disk_based_diagnostics_events_if_needed(
 9077        &mut self,
 9078        language_server_id: LanguageServerId,
 9079        cx: &mut Context<Self>,
 9080    ) {
 9081        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9082
 9083        let Some(LanguageServerState::Running {
 9084            simulate_disk_based_diagnostics_completion,
 9085            adapter,
 9086            ..
 9087        }) = self
 9088            .as_local_mut()
 9089            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9090        else {
 9091            return;
 9092        };
 9093
 9094        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9095            return;
 9096        }
 9097
 9098        let prev_task =
 9099            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9100                cx.background_executor()
 9101                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9102                    .await;
 9103
 9104                this.update(cx, |this, cx| {
 9105                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9106
 9107                    if let Some(LanguageServerState::Running {
 9108                        simulate_disk_based_diagnostics_completion,
 9109                        ..
 9110                    }) = this.as_local_mut().and_then(|local_store| {
 9111                        local_store.language_servers.get_mut(&language_server_id)
 9112                    }) {
 9113                        *simulate_disk_based_diagnostics_completion = None;
 9114                    }
 9115                })
 9116                .ok();
 9117            }));
 9118
 9119        if prev_task.is_none() {
 9120            self.disk_based_diagnostics_started(language_server_id, cx);
 9121        }
 9122    }
 9123
 9124    pub fn language_server_statuses(
 9125        &self,
 9126    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9127        self.language_server_statuses
 9128            .iter()
 9129            .map(|(key, value)| (*key, value))
 9130    }
 9131
 9132    pub(super) fn did_rename_entry(
 9133        &self,
 9134        worktree_id: WorktreeId,
 9135        old_path: &Path,
 9136        new_path: &Path,
 9137        is_dir: bool,
 9138    ) {
 9139        maybe!({
 9140            let local_store = self.as_local()?;
 9141
 9142            let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from)?;
 9143            let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from)?;
 9144
 9145            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9146                let Some(filter) = local_store
 9147                    .language_server_paths_watched_for_rename
 9148                    .get(&language_server.server_id())
 9149                else {
 9150                    continue;
 9151                };
 9152
 9153                if filter.should_send_did_rename(&old_uri, is_dir) {
 9154                    language_server
 9155                        .notify::<DidRenameFiles>(&RenameFilesParams {
 9156                            files: vec![FileRename {
 9157                                old_uri: old_uri.clone(),
 9158                                new_uri: new_uri.clone(),
 9159                            }],
 9160                        })
 9161                        .ok();
 9162                }
 9163            }
 9164            Some(())
 9165        });
 9166    }
 9167
 9168    pub(super) fn will_rename_entry(
 9169        this: WeakEntity<Self>,
 9170        worktree_id: WorktreeId,
 9171        old_path: &Path,
 9172        new_path: &Path,
 9173        is_dir: bool,
 9174        cx: AsyncApp,
 9175    ) -> Task<()> {
 9176        let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
 9177        let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
 9178        cx.spawn(async move |cx| {
 9179            let mut tasks = vec![];
 9180            this.update(cx, |this, cx| {
 9181                let local_store = this.as_local()?;
 9182                let old_uri = old_uri?;
 9183                let new_uri = new_uri?;
 9184                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9185                    let Some(filter) = local_store
 9186                        .language_server_paths_watched_for_rename
 9187                        .get(&language_server.server_id())
 9188                    else {
 9189                        continue;
 9190                    };
 9191
 9192                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9193                        let apply_edit = cx.spawn({
 9194                            let old_uri = old_uri.clone();
 9195                            let new_uri = new_uri.clone();
 9196                            let language_server = language_server.clone();
 9197                            async move |this, cx| {
 9198                                let edit = language_server
 9199                                    .request::<WillRenameFiles>(RenameFilesParams {
 9200                                        files: vec![FileRename { old_uri, new_uri }],
 9201                                    })
 9202                                    .await
 9203                                    .into_response()
 9204                                    .context("will rename files")
 9205                                    .log_err()
 9206                                    .flatten()?;
 9207
 9208                                LocalLspStore::deserialize_workspace_edit(
 9209                                    this.upgrade()?,
 9210                                    edit,
 9211                                    false,
 9212                                    language_server.clone(),
 9213                                    cx,
 9214                                )
 9215                                .await
 9216                                .ok();
 9217                                Some(())
 9218                            }
 9219                        });
 9220                        tasks.push(apply_edit);
 9221                    }
 9222                }
 9223                Some(())
 9224            })
 9225            .ok()
 9226            .flatten();
 9227            for task in tasks {
 9228                // Await on tasks sequentially so that the order of application of edits is deterministic
 9229                // (at least with regards to the order of registration of language servers)
 9230                task.await;
 9231            }
 9232        })
 9233    }
 9234
 9235    fn lsp_notify_abs_paths_changed(
 9236        &mut self,
 9237        server_id: LanguageServerId,
 9238        changes: Vec<PathEvent>,
 9239    ) {
 9240        maybe!({
 9241            let server = self.language_server_for_id(server_id)?;
 9242            let changes = changes
 9243                .into_iter()
 9244                .filter_map(|event| {
 9245                    let typ = match event.kind? {
 9246                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9247                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9248                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9249                    };
 9250                    Some(lsp::FileEvent {
 9251                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9252                        typ,
 9253                    })
 9254                })
 9255                .collect::<Vec<_>>();
 9256            if !changes.is_empty() {
 9257                server
 9258                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9259                        &lsp::DidChangeWatchedFilesParams { changes },
 9260                    )
 9261                    .ok();
 9262            }
 9263            Some(())
 9264        });
 9265    }
 9266
 9267    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9268        self.as_local()?.language_server_for_id(id)
 9269    }
 9270
 9271    fn on_lsp_progress(
 9272        &mut self,
 9273        progress: lsp::ProgressParams,
 9274        language_server_id: LanguageServerId,
 9275        disk_based_diagnostics_progress_token: Option<String>,
 9276        cx: &mut Context<Self>,
 9277    ) {
 9278        let token = match progress.token {
 9279            lsp::NumberOrString::String(token) => token,
 9280            lsp::NumberOrString::Number(token) => {
 9281                log::info!("skipping numeric progress token {}", token);
 9282                return;
 9283            }
 9284        };
 9285
 9286        match progress.value {
 9287            lsp::ProgressParamsValue::WorkDone(progress) => {
 9288                self.handle_work_done_progress(
 9289                    progress,
 9290                    language_server_id,
 9291                    disk_based_diagnostics_progress_token,
 9292                    token,
 9293                    cx,
 9294                );
 9295            }
 9296            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9297                if let Some(LanguageServerState::Running {
 9298                    workspace_refresh_task: Some(workspace_refresh_task),
 9299                    ..
 9300                }) = self
 9301                    .as_local_mut()
 9302                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9303                {
 9304                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9305                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9306                }
 9307            }
 9308        }
 9309    }
 9310
 9311    fn handle_work_done_progress(
 9312        &mut self,
 9313        progress: lsp::WorkDoneProgress,
 9314        language_server_id: LanguageServerId,
 9315        disk_based_diagnostics_progress_token: Option<String>,
 9316        token: String,
 9317        cx: &mut Context<Self>,
 9318    ) {
 9319        let language_server_status =
 9320            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9321                status
 9322            } else {
 9323                return;
 9324            };
 9325
 9326        if !language_server_status.progress_tokens.contains(&token) {
 9327            return;
 9328        }
 9329
 9330        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9331            .as_ref()
 9332            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9333
 9334        match progress {
 9335            lsp::WorkDoneProgress::Begin(report) => {
 9336                if is_disk_based_diagnostics_progress {
 9337                    self.disk_based_diagnostics_started(language_server_id, cx);
 9338                }
 9339                self.on_lsp_work_start(
 9340                    language_server_id,
 9341                    token.clone(),
 9342                    LanguageServerProgress {
 9343                        title: Some(report.title),
 9344                        is_disk_based_diagnostics_progress,
 9345                        is_cancellable: report.cancellable.unwrap_or(false),
 9346                        message: report.message.clone(),
 9347                        percentage: report.percentage.map(|p| p as usize),
 9348                        last_update_at: cx.background_executor().now(),
 9349                    },
 9350                    cx,
 9351                );
 9352            }
 9353            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9354                language_server_id,
 9355                token,
 9356                LanguageServerProgress {
 9357                    title: None,
 9358                    is_disk_based_diagnostics_progress,
 9359                    is_cancellable: report.cancellable.unwrap_or(false),
 9360                    message: report.message,
 9361                    percentage: report.percentage.map(|p| p as usize),
 9362                    last_update_at: cx.background_executor().now(),
 9363                },
 9364                cx,
 9365            ),
 9366            lsp::WorkDoneProgress::End(_) => {
 9367                language_server_status.progress_tokens.remove(&token);
 9368                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9369                if is_disk_based_diagnostics_progress {
 9370                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9371                }
 9372            }
 9373        }
 9374    }
 9375
 9376    fn on_lsp_work_start(
 9377        &mut self,
 9378        language_server_id: LanguageServerId,
 9379        token: String,
 9380        progress: LanguageServerProgress,
 9381        cx: &mut Context<Self>,
 9382    ) {
 9383        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9384            status.pending_work.insert(token.clone(), progress.clone());
 9385            cx.notify();
 9386        }
 9387        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9388            language_server_id,
 9389            name: self
 9390                .language_server_adapter_for_id(language_server_id)
 9391                .map(|adapter| adapter.name()),
 9392            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9393                token,
 9394                title: progress.title,
 9395                message: progress.message,
 9396                percentage: progress.percentage.map(|p| p as u32),
 9397                is_cancellable: Some(progress.is_cancellable),
 9398            }),
 9399        })
 9400    }
 9401
 9402    fn on_lsp_work_progress(
 9403        &mut self,
 9404        language_server_id: LanguageServerId,
 9405        token: String,
 9406        progress: LanguageServerProgress,
 9407        cx: &mut Context<Self>,
 9408    ) {
 9409        let mut did_update = false;
 9410        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9411            match status.pending_work.entry(token.clone()) {
 9412                btree_map::Entry::Vacant(entry) => {
 9413                    entry.insert(progress.clone());
 9414                    did_update = true;
 9415                }
 9416                btree_map::Entry::Occupied(mut entry) => {
 9417                    let entry = entry.get_mut();
 9418                    if (progress.last_update_at - entry.last_update_at)
 9419                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9420                    {
 9421                        entry.last_update_at = progress.last_update_at;
 9422                        if progress.message.is_some() {
 9423                            entry.message = progress.message.clone();
 9424                        }
 9425                        if progress.percentage.is_some() {
 9426                            entry.percentage = progress.percentage;
 9427                        }
 9428                        if progress.is_cancellable != entry.is_cancellable {
 9429                            entry.is_cancellable = progress.is_cancellable;
 9430                        }
 9431                        did_update = true;
 9432                    }
 9433                }
 9434            }
 9435        }
 9436
 9437        if did_update {
 9438            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9439                language_server_id,
 9440                name: self
 9441                    .language_server_adapter_for_id(language_server_id)
 9442                    .map(|adapter| adapter.name()),
 9443                message: proto::update_language_server::Variant::WorkProgress(
 9444                    proto::LspWorkProgress {
 9445                        token,
 9446                        message: progress.message,
 9447                        percentage: progress.percentage.map(|p| p as u32),
 9448                        is_cancellable: Some(progress.is_cancellable),
 9449                    },
 9450                ),
 9451            })
 9452        }
 9453    }
 9454
 9455    fn on_lsp_work_end(
 9456        &mut self,
 9457        language_server_id: LanguageServerId,
 9458        token: String,
 9459        cx: &mut Context<Self>,
 9460    ) {
 9461        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9462            if let Some(work) = status.pending_work.remove(&token)
 9463                && !work.is_disk_based_diagnostics_progress
 9464            {
 9465                cx.emit(LspStoreEvent::RefreshInlayHints);
 9466            }
 9467            cx.notify();
 9468        }
 9469
 9470        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9471            language_server_id,
 9472            name: self
 9473                .language_server_adapter_for_id(language_server_id)
 9474                .map(|adapter| adapter.name()),
 9475            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9476        })
 9477    }
 9478
 9479    pub async fn handle_resolve_completion_documentation(
 9480        this: Entity<Self>,
 9481        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9482        mut cx: AsyncApp,
 9483    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9484        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9485
 9486        let completion = this
 9487            .read_with(&cx, |this, cx| {
 9488                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9489                let server = this
 9490                    .language_server_for_id(id)
 9491                    .with_context(|| format!("No language server {id}"))?;
 9492
 9493                anyhow::Ok(cx.background_spawn(async move {
 9494                    let can_resolve = server
 9495                        .capabilities()
 9496                        .completion_provider
 9497                        .as_ref()
 9498                        .and_then(|options| options.resolve_provider)
 9499                        .unwrap_or(false);
 9500                    if can_resolve {
 9501                        server
 9502                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9503                            .await
 9504                            .into_response()
 9505                            .context("resolve completion item")
 9506                    } else {
 9507                        anyhow::Ok(lsp_completion)
 9508                    }
 9509                }))
 9510            })??
 9511            .await?;
 9512
 9513        let mut documentation_is_markdown = false;
 9514        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9515        let documentation = match completion.documentation {
 9516            Some(lsp::Documentation::String(text)) => text,
 9517
 9518            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9519                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9520                value
 9521            }
 9522
 9523            _ => String::new(),
 9524        };
 9525
 9526        // If we have a new buffer_id, that means we're talking to a new client
 9527        // and want to check for new text_edits in the completion too.
 9528        let mut old_replace_start = None;
 9529        let mut old_replace_end = None;
 9530        let mut old_insert_start = None;
 9531        let mut old_insert_end = None;
 9532        let mut new_text = String::default();
 9533        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9534            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9535                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9536                anyhow::Ok(buffer.read(cx).snapshot())
 9537            })??;
 9538
 9539            if let Some(text_edit) = completion.text_edit.as_ref() {
 9540                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9541
 9542                if let Some(mut edit) = edit {
 9543                    LineEnding::normalize(&mut edit.new_text);
 9544
 9545                    new_text = edit.new_text;
 9546                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9547                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9548                    if let Some(insert_range) = edit.insert_range {
 9549                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9550                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9551                    }
 9552                }
 9553            }
 9554        }
 9555
 9556        Ok(proto::ResolveCompletionDocumentationResponse {
 9557            documentation,
 9558            documentation_is_markdown,
 9559            old_replace_start,
 9560            old_replace_end,
 9561            new_text,
 9562            lsp_completion,
 9563            old_insert_start,
 9564            old_insert_end,
 9565        })
 9566    }
 9567
 9568    async fn handle_on_type_formatting(
 9569        this: Entity<Self>,
 9570        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9571        mut cx: AsyncApp,
 9572    ) -> Result<proto::OnTypeFormattingResponse> {
 9573        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9574            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9575            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9576            let position = envelope
 9577                .payload
 9578                .position
 9579                .and_then(deserialize_anchor)
 9580                .context("invalid position")?;
 9581            anyhow::Ok(this.apply_on_type_formatting(
 9582                buffer,
 9583                position,
 9584                envelope.payload.trigger.clone(),
 9585                cx,
 9586            ))
 9587        })??;
 9588
 9589        let transaction = on_type_formatting
 9590            .await?
 9591            .as_ref()
 9592            .map(language::proto::serialize_transaction);
 9593        Ok(proto::OnTypeFormattingResponse { transaction })
 9594    }
 9595
 9596    async fn handle_refresh_inlay_hints(
 9597        this: Entity<Self>,
 9598        _: TypedEnvelope<proto::RefreshInlayHints>,
 9599        mut cx: AsyncApp,
 9600    ) -> Result<proto::Ack> {
 9601        this.update(&mut cx, |_, cx| {
 9602            cx.emit(LspStoreEvent::RefreshInlayHints);
 9603        })?;
 9604        Ok(proto::Ack {})
 9605    }
 9606
 9607    async fn handle_pull_workspace_diagnostics(
 9608        lsp_store: Entity<Self>,
 9609        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9610        mut cx: AsyncApp,
 9611    ) -> Result<proto::Ack> {
 9612        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9613        lsp_store.update(&mut cx, |lsp_store, _| {
 9614            lsp_store.pull_workspace_diagnostics(server_id);
 9615        })?;
 9616        Ok(proto::Ack {})
 9617    }
 9618
 9619    async fn handle_inlay_hints(
 9620        this: Entity<Self>,
 9621        envelope: TypedEnvelope<proto::InlayHints>,
 9622        mut cx: AsyncApp,
 9623    ) -> Result<proto::InlayHintsResponse> {
 9624        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9625        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9626        let buffer = this.update(&mut cx, |this, cx| {
 9627            this.buffer_store.read(cx).get_existing(buffer_id)
 9628        })??;
 9629        buffer
 9630            .update(&mut cx, |buffer, _| {
 9631                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9632            })?
 9633            .await
 9634            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9635
 9636        let start = envelope
 9637            .payload
 9638            .start
 9639            .and_then(deserialize_anchor)
 9640            .context("missing range start")?;
 9641        let end = envelope
 9642            .payload
 9643            .end
 9644            .and_then(deserialize_anchor)
 9645            .context("missing range end")?;
 9646        let buffer_hints = this
 9647            .update(&mut cx, |lsp_store, cx| {
 9648                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9649            })?
 9650            .await
 9651            .context("inlay hints fetch")?;
 9652
 9653        this.update(&mut cx, |project, cx| {
 9654            InlayHints::response_to_proto(
 9655                buffer_hints,
 9656                project,
 9657                sender_id,
 9658                &buffer.read(cx).version(),
 9659                cx,
 9660            )
 9661        })
 9662    }
 9663
 9664    async fn handle_get_color_presentation(
 9665        lsp_store: Entity<Self>,
 9666        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9667        mut cx: AsyncApp,
 9668    ) -> Result<proto::GetColorPresentationResponse> {
 9669        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9670        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9671            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9672        })??;
 9673
 9674        let color = envelope
 9675            .payload
 9676            .color
 9677            .context("invalid color resolve request")?;
 9678        let start = color
 9679            .lsp_range_start
 9680            .context("invalid color resolve request")?;
 9681        let end = color
 9682            .lsp_range_end
 9683            .context("invalid color resolve request")?;
 9684
 9685        let color = DocumentColor {
 9686            lsp_range: lsp::Range {
 9687                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9688                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9689            },
 9690            color: lsp::Color {
 9691                red: color.red,
 9692                green: color.green,
 9693                blue: color.blue,
 9694                alpha: color.alpha,
 9695            },
 9696            resolved: false,
 9697            color_presentations: Vec::new(),
 9698        };
 9699        let resolved_color = lsp_store
 9700            .update(&mut cx, |lsp_store, cx| {
 9701                lsp_store.resolve_color_presentation(
 9702                    color,
 9703                    buffer.clone(),
 9704                    LanguageServerId(envelope.payload.server_id as usize),
 9705                    cx,
 9706                )
 9707            })?
 9708            .await
 9709            .context("resolving color presentation")?;
 9710
 9711        Ok(proto::GetColorPresentationResponse {
 9712            presentations: resolved_color
 9713                .color_presentations
 9714                .into_iter()
 9715                .map(|presentation| proto::ColorPresentation {
 9716                    label: presentation.label.to_string(),
 9717                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9718                    additional_text_edits: presentation
 9719                        .additional_text_edits
 9720                        .into_iter()
 9721                        .map(serialize_lsp_edit)
 9722                        .collect(),
 9723                })
 9724                .collect(),
 9725        })
 9726    }
 9727
 9728    async fn handle_resolve_inlay_hint(
 9729        this: Entity<Self>,
 9730        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9731        mut cx: AsyncApp,
 9732    ) -> Result<proto::ResolveInlayHintResponse> {
 9733        let proto_hint = envelope
 9734            .payload
 9735            .hint
 9736            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9737        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9738            .context("resolved proto inlay hint conversion")?;
 9739        let buffer = this.update(&mut cx, |this, cx| {
 9740            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9741            this.buffer_store.read(cx).get_existing(buffer_id)
 9742        })??;
 9743        let response_hint = this
 9744            .update(&mut cx, |this, cx| {
 9745                this.resolve_inlay_hint(
 9746                    hint,
 9747                    buffer,
 9748                    LanguageServerId(envelope.payload.language_server_id as usize),
 9749                    cx,
 9750                )
 9751            })?
 9752            .await
 9753            .context("inlay hints fetch")?;
 9754        Ok(proto::ResolveInlayHintResponse {
 9755            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9756        })
 9757    }
 9758
 9759    async fn handle_refresh_code_lens(
 9760        this: Entity<Self>,
 9761        _: TypedEnvelope<proto::RefreshCodeLens>,
 9762        mut cx: AsyncApp,
 9763    ) -> Result<proto::Ack> {
 9764        this.update(&mut cx, |_, cx| {
 9765            cx.emit(LspStoreEvent::RefreshCodeLens);
 9766        })?;
 9767        Ok(proto::Ack {})
 9768    }
 9769
 9770    async fn handle_open_buffer_for_symbol(
 9771        this: Entity<Self>,
 9772        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9773        mut cx: AsyncApp,
 9774    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9775        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9776        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9777        let symbol = Self::deserialize_symbol(symbol)?;
 9778        let symbol = this.read_with(&cx, |this, _| {
 9779            let signature = this.symbol_signature(&symbol.path);
 9780            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9781            Ok(symbol)
 9782        })??;
 9783        let buffer = this
 9784            .update(&mut cx, |this, cx| {
 9785                this.open_buffer_for_symbol(
 9786                    &Symbol {
 9787                        language_server_name: symbol.language_server_name,
 9788                        source_worktree_id: symbol.source_worktree_id,
 9789                        source_language_server_id: symbol.source_language_server_id,
 9790                        path: symbol.path,
 9791                        name: symbol.name,
 9792                        kind: symbol.kind,
 9793                        range: symbol.range,
 9794                        signature: symbol.signature,
 9795                        label: CodeLabel {
 9796                            text: Default::default(),
 9797                            runs: Default::default(),
 9798                            filter_range: Default::default(),
 9799                        },
 9800                    },
 9801                    cx,
 9802                )
 9803            })?
 9804            .await?;
 9805
 9806        this.update(&mut cx, |this, cx| {
 9807            let is_private = buffer
 9808                .read(cx)
 9809                .file()
 9810                .map(|f| f.is_private())
 9811                .unwrap_or_default();
 9812            if is_private {
 9813                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9814            } else {
 9815                this.buffer_store
 9816                    .update(cx, |buffer_store, cx| {
 9817                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9818                    })
 9819                    .detach_and_log_err(cx);
 9820                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9821                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9822            }
 9823        })?
 9824    }
 9825
 9826    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9827        let mut hasher = Sha256::new();
 9828        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9829        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9830        hasher.update(self.nonce.to_be_bytes());
 9831        hasher.finalize().as_slice().try_into().unwrap()
 9832    }
 9833
 9834    pub async fn handle_get_project_symbols(
 9835        this: Entity<Self>,
 9836        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9837        mut cx: AsyncApp,
 9838    ) -> Result<proto::GetProjectSymbolsResponse> {
 9839        let symbols = this
 9840            .update(&mut cx, |this, cx| {
 9841                this.symbols(&envelope.payload.query, cx)
 9842            })?
 9843            .await?;
 9844
 9845        Ok(proto::GetProjectSymbolsResponse {
 9846            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9847        })
 9848    }
 9849
 9850    pub async fn handle_restart_language_servers(
 9851        this: Entity<Self>,
 9852        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9853        mut cx: AsyncApp,
 9854    ) -> Result<proto::Ack> {
 9855        this.update(&mut cx, |lsp_store, cx| {
 9856            let buffers =
 9857                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9858            lsp_store.restart_language_servers_for_buffers(
 9859                buffers,
 9860                envelope
 9861                    .payload
 9862                    .only_servers
 9863                    .into_iter()
 9864                    .filter_map(|selector| {
 9865                        Some(match selector.selector? {
 9866                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9867                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9868                            }
 9869                            proto::language_server_selector::Selector::Name(name) => {
 9870                                LanguageServerSelector::Name(LanguageServerName(
 9871                                    SharedString::from(name),
 9872                                ))
 9873                            }
 9874                        })
 9875                    })
 9876                    .collect(),
 9877                cx,
 9878            );
 9879        })?;
 9880
 9881        Ok(proto::Ack {})
 9882    }
 9883
 9884    pub async fn handle_stop_language_servers(
 9885        lsp_store: Entity<Self>,
 9886        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9887        mut cx: AsyncApp,
 9888    ) -> Result<proto::Ack> {
 9889        lsp_store.update(&mut cx, |lsp_store, cx| {
 9890            if envelope.payload.all
 9891                && envelope.payload.also_servers.is_empty()
 9892                && envelope.payload.buffer_ids.is_empty()
 9893            {
 9894                lsp_store.stop_all_language_servers(cx);
 9895            } else {
 9896                let buffers =
 9897                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9898                lsp_store
 9899                    .stop_language_servers_for_buffers(
 9900                        buffers,
 9901                        envelope
 9902                            .payload
 9903                            .also_servers
 9904                            .into_iter()
 9905                            .filter_map(|selector| {
 9906                                Some(match selector.selector? {
 9907                                    proto::language_server_selector::Selector::ServerId(
 9908                                        server_id,
 9909                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9910                                        server_id,
 9911                                    )),
 9912                                    proto::language_server_selector::Selector::Name(name) => {
 9913                                        LanguageServerSelector::Name(LanguageServerName(
 9914                                            SharedString::from(name),
 9915                                        ))
 9916                                    }
 9917                                })
 9918                            })
 9919                            .collect(),
 9920                        cx,
 9921                    )
 9922                    .detach_and_log_err(cx);
 9923            }
 9924        })?;
 9925
 9926        Ok(proto::Ack {})
 9927    }
 9928
 9929    pub async fn handle_cancel_language_server_work(
 9930        this: Entity<Self>,
 9931        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9932        mut cx: AsyncApp,
 9933    ) -> Result<proto::Ack> {
 9934        this.update(&mut cx, |this, cx| {
 9935            if let Some(work) = envelope.payload.work {
 9936                match work {
 9937                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9938                        let buffers =
 9939                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9940                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9941                    }
 9942                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9943                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9944                        this.cancel_language_server_work(server_id, work.token, cx);
 9945                    }
 9946                }
 9947            }
 9948        })?;
 9949
 9950        Ok(proto::Ack {})
 9951    }
 9952
 9953    fn buffer_ids_to_buffers(
 9954        &mut self,
 9955        buffer_ids: impl Iterator<Item = u64>,
 9956        cx: &mut Context<Self>,
 9957    ) -> Vec<Entity<Buffer>> {
 9958        buffer_ids
 9959            .into_iter()
 9960            .flat_map(|buffer_id| {
 9961                self.buffer_store
 9962                    .read(cx)
 9963                    .get(BufferId::new(buffer_id).log_err()?)
 9964            })
 9965            .collect::<Vec<_>>()
 9966    }
 9967
 9968    async fn handle_apply_additional_edits_for_completion(
 9969        this: Entity<Self>,
 9970        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
 9971        mut cx: AsyncApp,
 9972    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
 9973        let (buffer, completion) = this.update(&mut cx, |this, cx| {
 9974            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9975            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9976            let completion = Self::deserialize_completion(
 9977                envelope.payload.completion.context("invalid completion")?,
 9978            )?;
 9979            anyhow::Ok((buffer, completion))
 9980        })??;
 9981
 9982        let apply_additional_edits = this.update(&mut cx, |this, cx| {
 9983            this.apply_additional_edits_for_completion(
 9984                buffer,
 9985                Rc::new(RefCell::new(Box::new([Completion {
 9986                    replace_range: completion.replace_range,
 9987                    new_text: completion.new_text,
 9988                    source: completion.source,
 9989                    documentation: None,
 9990                    label: CodeLabel {
 9991                        text: Default::default(),
 9992                        runs: Default::default(),
 9993                        filter_range: Default::default(),
 9994                    },
 9995                    insert_text_mode: None,
 9996                    icon_path: None,
 9997                    confirm: None,
 9998                }]))),
 9999                0,
10000                false,
10001                cx,
10002            )
10003        })?;
10004
10005        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10006            transaction: apply_additional_edits
10007                .await?
10008                .as_ref()
10009                .map(language::proto::serialize_transaction),
10010        })
10011    }
10012
10013    pub fn last_formatting_failure(&self) -> Option<&str> {
10014        self.last_formatting_failure.as_deref()
10015    }
10016
10017    pub fn reset_last_formatting_failure(&mut self) {
10018        self.last_formatting_failure = None;
10019    }
10020
10021    pub fn environment_for_buffer(
10022        &self,
10023        buffer: &Entity<Buffer>,
10024        cx: &mut Context<Self>,
10025    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10026        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10027            environment.update(cx, |env, cx| {
10028                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10029            })
10030        } else {
10031            Task::ready(None).shared()
10032        }
10033    }
10034
10035    pub fn format(
10036        &mut self,
10037        buffers: HashSet<Entity<Buffer>>,
10038        target: LspFormatTarget,
10039        push_to_history: bool,
10040        trigger: FormatTrigger,
10041        cx: &mut Context<Self>,
10042    ) -> Task<anyhow::Result<ProjectTransaction>> {
10043        let logger = zlog::scoped!("format");
10044        if self.as_local().is_some() {
10045            zlog::trace!(logger => "Formatting locally");
10046            let logger = zlog::scoped!(logger => "local");
10047            let buffers = buffers
10048                .into_iter()
10049                .map(|buffer_handle| {
10050                    let buffer = buffer_handle.read(cx);
10051                    let buffer_abs_path = File::from_dyn(buffer.file())
10052                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10053
10054                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10055                })
10056                .collect::<Vec<_>>();
10057
10058            cx.spawn(async move |lsp_store, cx| {
10059                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10060
10061                for (handle, abs_path, id) in buffers {
10062                    let env = lsp_store
10063                        .update(cx, |lsp_store, cx| {
10064                            lsp_store.environment_for_buffer(&handle, cx)
10065                        })?
10066                        .await;
10067
10068                    let ranges = match &target {
10069                        LspFormatTarget::Buffers => None,
10070                        LspFormatTarget::Ranges(ranges) => {
10071                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10072                        }
10073                    };
10074
10075                    formattable_buffers.push(FormattableBuffer {
10076                        handle,
10077                        abs_path,
10078                        env,
10079                        ranges,
10080                    });
10081                }
10082                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10083
10084                let format_timer = zlog::time!(logger => "Formatting buffers");
10085                let result = LocalLspStore::format_locally(
10086                    lsp_store.clone(),
10087                    formattable_buffers,
10088                    push_to_history,
10089                    trigger,
10090                    logger,
10091                    cx,
10092                )
10093                .await;
10094                format_timer.end();
10095
10096                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10097
10098                lsp_store.update(cx, |lsp_store, _| {
10099                    lsp_store.update_last_formatting_failure(&result);
10100                })?;
10101
10102                result
10103            })
10104        } else if let Some((client, project_id)) = self.upstream_client() {
10105            zlog::trace!(logger => "Formatting remotely");
10106            let logger = zlog::scoped!(logger => "remote");
10107            // Don't support formatting ranges via remote
10108            match target {
10109                LspFormatTarget::Buffers => {}
10110                LspFormatTarget::Ranges(_) => {
10111                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10112                    return Task::ready(Ok(ProjectTransaction::default()));
10113                }
10114            }
10115
10116            let buffer_store = self.buffer_store();
10117            cx.spawn(async move |lsp_store, cx| {
10118                zlog::trace!(logger => "Sending remote format request");
10119                let request_timer = zlog::time!(logger => "remote format request");
10120                let result = client
10121                    .request(proto::FormatBuffers {
10122                        project_id,
10123                        trigger: trigger as i32,
10124                        buffer_ids: buffers
10125                            .iter()
10126                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10127                            .collect::<Result<_>>()?,
10128                    })
10129                    .await
10130                    .and_then(|result| result.transaction.context("missing transaction"));
10131                request_timer.end();
10132
10133                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10134
10135                lsp_store.update(cx, |lsp_store, _| {
10136                    lsp_store.update_last_formatting_failure(&result);
10137                })?;
10138
10139                let transaction_response = result?;
10140                let _timer = zlog::time!(logger => "deserializing project transaction");
10141                buffer_store
10142                    .update(cx, |buffer_store, cx| {
10143                        buffer_store.deserialize_project_transaction(
10144                            transaction_response,
10145                            push_to_history,
10146                            cx,
10147                        )
10148                    })?
10149                    .await
10150            })
10151        } else {
10152            zlog::trace!(logger => "Not formatting");
10153            Task::ready(Ok(ProjectTransaction::default()))
10154        }
10155    }
10156
10157    async fn handle_format_buffers(
10158        this: Entity<Self>,
10159        envelope: TypedEnvelope<proto::FormatBuffers>,
10160        mut cx: AsyncApp,
10161    ) -> Result<proto::FormatBuffersResponse> {
10162        let sender_id = envelope.original_sender_id().unwrap_or_default();
10163        let format = this.update(&mut cx, |this, cx| {
10164            let mut buffers = HashSet::default();
10165            for buffer_id in &envelope.payload.buffer_ids {
10166                let buffer_id = BufferId::new(*buffer_id)?;
10167                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10168            }
10169            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10170            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10171        })??;
10172
10173        let project_transaction = format.await?;
10174        let project_transaction = this.update(&mut cx, |this, cx| {
10175            this.buffer_store.update(cx, |buffer_store, cx| {
10176                buffer_store.serialize_project_transaction_for_peer(
10177                    project_transaction,
10178                    sender_id,
10179                    cx,
10180                )
10181            })
10182        })?;
10183        Ok(proto::FormatBuffersResponse {
10184            transaction: Some(project_transaction),
10185        })
10186    }
10187
10188    async fn handle_apply_code_action_kind(
10189        this: Entity<Self>,
10190        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10191        mut cx: AsyncApp,
10192    ) -> Result<proto::ApplyCodeActionKindResponse> {
10193        let sender_id = envelope.original_sender_id().unwrap_or_default();
10194        let format = this.update(&mut cx, |this, cx| {
10195            let mut buffers = HashSet::default();
10196            for buffer_id in &envelope.payload.buffer_ids {
10197                let buffer_id = BufferId::new(*buffer_id)?;
10198                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10199            }
10200            let kind = match envelope.payload.kind.as_str() {
10201                "" => CodeActionKind::EMPTY,
10202                "quickfix" => CodeActionKind::QUICKFIX,
10203                "refactor" => CodeActionKind::REFACTOR,
10204                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10205                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10206                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10207                "source" => CodeActionKind::SOURCE,
10208                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10209                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10210                _ => anyhow::bail!(
10211                    "Invalid code action kind {}",
10212                    envelope.payload.kind.as_str()
10213                ),
10214            };
10215            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10216        })??;
10217
10218        let project_transaction = format.await?;
10219        let project_transaction = this.update(&mut cx, |this, cx| {
10220            this.buffer_store.update(cx, |buffer_store, cx| {
10221                buffer_store.serialize_project_transaction_for_peer(
10222                    project_transaction,
10223                    sender_id,
10224                    cx,
10225                )
10226            })
10227        })?;
10228        Ok(proto::ApplyCodeActionKindResponse {
10229            transaction: Some(project_transaction),
10230        })
10231    }
10232
10233    async fn shutdown_language_server(
10234        server_state: Option<LanguageServerState>,
10235        name: LanguageServerName,
10236        cx: &mut AsyncApp,
10237    ) {
10238        let server = match server_state {
10239            Some(LanguageServerState::Starting { startup, .. }) => {
10240                let mut timer = cx
10241                    .background_executor()
10242                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10243                    .fuse();
10244
10245                select! {
10246                    server = startup.fuse() => server,
10247                    () = timer => {
10248                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10249                        None
10250                    },
10251                }
10252            }
10253
10254            Some(LanguageServerState::Running { server, .. }) => Some(server),
10255
10256            None => None,
10257        };
10258
10259        if let Some(server) = server
10260            && let Some(shutdown) = server.shutdown()
10261        {
10262            shutdown.await;
10263        }
10264    }
10265
10266    // Returns a list of all of the worktrees which no longer have a language server and the root path
10267    // for the stopped server
10268    fn stop_local_language_server(
10269        &mut self,
10270        server_id: LanguageServerId,
10271        cx: &mut Context<Self>,
10272    ) -> Task<()> {
10273        let local = match &mut self.mode {
10274            LspStoreMode::Local(local) => local,
10275            _ => {
10276                return Task::ready(());
10277            }
10278        };
10279
10280        // Remove this server ID from all entries in the given worktree.
10281        local
10282            .language_server_ids
10283            .retain(|_, state| state.id != server_id);
10284        self.buffer_store.update(cx, |buffer_store, cx| {
10285            for buffer in buffer_store.buffers() {
10286                buffer.update(cx, |buffer, cx| {
10287                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10288                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10289                });
10290            }
10291        });
10292
10293        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10294            summaries.retain(|path, summaries_by_server_id| {
10295                if summaries_by_server_id.remove(&server_id).is_some() {
10296                    if let Some((client, project_id)) = self.downstream_client.clone() {
10297                        client
10298                            .send(proto::UpdateDiagnosticSummary {
10299                                project_id,
10300                                worktree_id: worktree_id.to_proto(),
10301                                summary: Some(proto::DiagnosticSummary {
10302                                    path: path.as_ref().to_proto(),
10303                                    language_server_id: server_id.0 as u64,
10304                                    error_count: 0,
10305                                    warning_count: 0,
10306                                }),
10307                                more_summaries: Vec::new(),
10308                            })
10309                            .log_err();
10310                    }
10311                    !summaries_by_server_id.is_empty()
10312                } else {
10313                    true
10314                }
10315            });
10316        }
10317
10318        let local = self.as_local_mut().unwrap();
10319        for diagnostics in local.diagnostics.values_mut() {
10320            diagnostics.retain(|_, diagnostics_by_server_id| {
10321                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10322                    diagnostics_by_server_id.remove(ix);
10323                    !diagnostics_by_server_id.is_empty()
10324                } else {
10325                    true
10326                }
10327            });
10328        }
10329        local.language_server_watched_paths.remove(&server_id);
10330
10331        let server_state = local.language_servers.remove(&server_id);
10332        self.cleanup_lsp_data(server_id);
10333        let name = self
10334            .language_server_statuses
10335            .remove(&server_id)
10336            .map(|status| status.name)
10337            .or_else(|| {
10338                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10339                    Some(adapter.name())
10340                } else {
10341                    None
10342                }
10343            });
10344
10345        if let Some(name) = name {
10346            log::info!("stopping language server {name}");
10347            self.languages
10348                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10349            cx.notify();
10350
10351            return cx.spawn(async move |lsp_store, cx| {
10352                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10353                lsp_store
10354                    .update(cx, |lsp_store, cx| {
10355                        lsp_store
10356                            .languages
10357                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10358                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10359                        cx.notify();
10360                    })
10361                    .ok();
10362            });
10363        }
10364
10365        if server_state.is_some() {
10366            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10367        }
10368        Task::ready(())
10369    }
10370
10371    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10372        if let Some((client, project_id)) = self.upstream_client() {
10373            let request = client.request(proto::StopLanguageServers {
10374                project_id,
10375                buffer_ids: Vec::new(),
10376                also_servers: Vec::new(),
10377                all: true,
10378            });
10379            cx.background_spawn(request).detach_and_log_err(cx);
10380        } else {
10381            let Some(local) = self.as_local_mut() else {
10382                return;
10383            };
10384            let language_servers_to_stop = local
10385                .language_server_ids
10386                .values()
10387                .map(|state| state.id)
10388                .collect();
10389            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10390            let tasks = language_servers_to_stop
10391                .into_iter()
10392                .map(|server| self.stop_local_language_server(server, cx))
10393                .collect::<Vec<_>>();
10394            cx.background_spawn(async move {
10395                futures::future::join_all(tasks).await;
10396            })
10397            .detach();
10398        }
10399    }
10400
10401    pub fn restart_language_servers_for_buffers(
10402        &mut self,
10403        buffers: Vec<Entity<Buffer>>,
10404        only_restart_servers: HashSet<LanguageServerSelector>,
10405        cx: &mut Context<Self>,
10406    ) {
10407        if let Some((client, project_id)) = self.upstream_client() {
10408            let request = client.request(proto::RestartLanguageServers {
10409                project_id,
10410                buffer_ids: buffers
10411                    .into_iter()
10412                    .map(|b| b.read(cx).remote_id().to_proto())
10413                    .collect(),
10414                only_servers: only_restart_servers
10415                    .into_iter()
10416                    .map(|selector| {
10417                        let selector = match selector {
10418                            LanguageServerSelector::Id(language_server_id) => {
10419                                proto::language_server_selector::Selector::ServerId(
10420                                    language_server_id.to_proto(),
10421                                )
10422                            }
10423                            LanguageServerSelector::Name(language_server_name) => {
10424                                proto::language_server_selector::Selector::Name(
10425                                    language_server_name.to_string(),
10426                                )
10427                            }
10428                        };
10429                        proto::LanguageServerSelector {
10430                            selector: Some(selector),
10431                        }
10432                    })
10433                    .collect(),
10434                all: false,
10435            });
10436            cx.background_spawn(request).detach_and_log_err(cx);
10437        } else {
10438            let stop_task = if only_restart_servers.is_empty() {
10439                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10440            } else {
10441                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10442            };
10443            cx.spawn(async move |lsp_store, cx| {
10444                stop_task.await;
10445                lsp_store
10446                    .update(cx, |lsp_store, cx| {
10447                        for buffer in buffers {
10448                            lsp_store.register_buffer_with_language_servers(
10449                                &buffer,
10450                                only_restart_servers.clone(),
10451                                true,
10452                                cx,
10453                            );
10454                        }
10455                    })
10456                    .ok()
10457            })
10458            .detach();
10459        }
10460    }
10461
10462    pub fn stop_language_servers_for_buffers(
10463        &mut self,
10464        buffers: Vec<Entity<Buffer>>,
10465        also_stop_servers: HashSet<LanguageServerSelector>,
10466        cx: &mut Context<Self>,
10467    ) -> Task<Result<()>> {
10468        if let Some((client, project_id)) = self.upstream_client() {
10469            let request = client.request(proto::StopLanguageServers {
10470                project_id,
10471                buffer_ids: buffers
10472                    .into_iter()
10473                    .map(|b| b.read(cx).remote_id().to_proto())
10474                    .collect(),
10475                also_servers: also_stop_servers
10476                    .into_iter()
10477                    .map(|selector| {
10478                        let selector = match selector {
10479                            LanguageServerSelector::Id(language_server_id) => {
10480                                proto::language_server_selector::Selector::ServerId(
10481                                    language_server_id.to_proto(),
10482                                )
10483                            }
10484                            LanguageServerSelector::Name(language_server_name) => {
10485                                proto::language_server_selector::Selector::Name(
10486                                    language_server_name.to_string(),
10487                                )
10488                            }
10489                        };
10490                        proto::LanguageServerSelector {
10491                            selector: Some(selector),
10492                        }
10493                    })
10494                    .collect(),
10495                all: false,
10496            });
10497            cx.background_spawn(async move {
10498                let _ = request.await?;
10499                Ok(())
10500            })
10501        } else {
10502            let task =
10503                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10504            cx.background_spawn(async move {
10505                task.await;
10506                Ok(())
10507            })
10508        }
10509    }
10510
10511    fn stop_local_language_servers_for_buffers(
10512        &mut self,
10513        buffers: &[Entity<Buffer>],
10514        also_stop_servers: HashSet<LanguageServerSelector>,
10515        cx: &mut Context<Self>,
10516    ) -> Task<()> {
10517        let Some(local) = self.as_local_mut() else {
10518            return Task::ready(());
10519        };
10520        let mut language_server_names_to_stop = BTreeSet::default();
10521        let mut language_servers_to_stop = also_stop_servers
10522            .into_iter()
10523            .flat_map(|selector| match selector {
10524                LanguageServerSelector::Id(id) => Some(id),
10525                LanguageServerSelector::Name(name) => {
10526                    language_server_names_to_stop.insert(name);
10527                    None
10528                }
10529            })
10530            .collect::<BTreeSet<_>>();
10531
10532        let mut covered_worktrees = HashSet::default();
10533        for buffer in buffers {
10534            buffer.update(cx, |buffer, cx| {
10535                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10536                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10537                    && covered_worktrees.insert(worktree_id)
10538                {
10539                    language_server_names_to_stop.retain(|name| {
10540                        let old_ids_count = language_servers_to_stop.len();
10541                        let all_language_servers_with_this_name = local
10542                            .language_server_ids
10543                            .iter()
10544                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10545                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10546                        old_ids_count == language_servers_to_stop.len()
10547                    });
10548                }
10549            });
10550        }
10551        for name in language_server_names_to_stop {
10552            language_servers_to_stop.extend(
10553                local
10554                    .language_server_ids
10555                    .iter()
10556                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10557            );
10558        }
10559
10560        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10561        let tasks = language_servers_to_stop
10562            .into_iter()
10563            .map(|server| self.stop_local_language_server(server, cx))
10564            .collect::<Vec<_>>();
10565
10566        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10567    }
10568
10569    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10570        let (worktree, relative_path) =
10571            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10572
10573        let project_path = ProjectPath {
10574            worktree_id: worktree.read(cx).id(),
10575            path: relative_path.into(),
10576        };
10577
10578        Some(
10579            self.buffer_store()
10580                .read(cx)
10581                .get_by_path(&project_path)?
10582                .read(cx),
10583        )
10584    }
10585
10586    #[cfg(any(test, feature = "test-support"))]
10587    pub fn update_diagnostics(
10588        &mut self,
10589        server_id: LanguageServerId,
10590        diagnostics: lsp::PublishDiagnosticsParams,
10591        result_id: Option<String>,
10592        source_kind: DiagnosticSourceKind,
10593        disk_based_sources: &[String],
10594        cx: &mut Context<Self>,
10595    ) -> Result<()> {
10596        self.merge_lsp_diagnostics(
10597            source_kind,
10598            vec![DocumentDiagnosticsUpdate {
10599                diagnostics,
10600                result_id,
10601                server_id,
10602                disk_based_sources: Cow::Borrowed(disk_based_sources),
10603            }],
10604            |_, _, _| false,
10605            cx,
10606        )
10607    }
10608
10609    pub fn merge_lsp_diagnostics(
10610        &mut self,
10611        source_kind: DiagnosticSourceKind,
10612        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10613        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10614        cx: &mut Context<Self>,
10615    ) -> Result<()> {
10616        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10617        let updates = lsp_diagnostics
10618            .into_iter()
10619            .filter_map(|update| {
10620                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10621                Some(DocumentDiagnosticsUpdate {
10622                    diagnostics: self.lsp_to_document_diagnostics(
10623                        abs_path,
10624                        source_kind,
10625                        update.server_id,
10626                        update.diagnostics,
10627                        &update.disk_based_sources,
10628                    ),
10629                    result_id: update.result_id,
10630                    server_id: update.server_id,
10631                    disk_based_sources: update.disk_based_sources,
10632                })
10633            })
10634            .collect();
10635        self.merge_diagnostic_entries(updates, merge, cx)?;
10636        Ok(())
10637    }
10638
10639    fn lsp_to_document_diagnostics(
10640        &mut self,
10641        document_abs_path: PathBuf,
10642        source_kind: DiagnosticSourceKind,
10643        server_id: LanguageServerId,
10644        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10645        disk_based_sources: &[String],
10646    ) -> DocumentDiagnostics {
10647        let mut diagnostics = Vec::default();
10648        let mut primary_diagnostic_group_ids = HashMap::default();
10649        let mut sources_by_group_id = HashMap::default();
10650        let mut supporting_diagnostics = HashMap::default();
10651
10652        let adapter = self.language_server_adapter_for_id(server_id);
10653
10654        // Ensure that primary diagnostics are always the most severe
10655        lsp_diagnostics
10656            .diagnostics
10657            .sort_by_key(|item| item.severity);
10658
10659        for diagnostic in &lsp_diagnostics.diagnostics {
10660            let source = diagnostic.source.as_ref();
10661            let range = range_from_lsp(diagnostic.range);
10662            let is_supporting = diagnostic
10663                .related_information
10664                .as_ref()
10665                .is_some_and(|infos| {
10666                    infos.iter().any(|info| {
10667                        primary_diagnostic_group_ids.contains_key(&(
10668                            source,
10669                            diagnostic.code.clone(),
10670                            range_from_lsp(info.location.range),
10671                        ))
10672                    })
10673                });
10674
10675            let is_unnecessary = diagnostic
10676                .tags
10677                .as_ref()
10678                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10679
10680            let underline = self
10681                .language_server_adapter_for_id(server_id)
10682                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10683
10684            if is_supporting {
10685                supporting_diagnostics.insert(
10686                    (source, diagnostic.code.clone(), range),
10687                    (diagnostic.severity, is_unnecessary),
10688                );
10689            } else {
10690                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10691                let is_disk_based =
10692                    source.is_some_and(|source| disk_based_sources.contains(source));
10693
10694                sources_by_group_id.insert(group_id, source);
10695                primary_diagnostic_group_ids
10696                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10697
10698                diagnostics.push(DiagnosticEntry {
10699                    range,
10700                    diagnostic: Diagnostic {
10701                        source: diagnostic.source.clone(),
10702                        source_kind,
10703                        code: diagnostic.code.clone(),
10704                        code_description: diagnostic
10705                            .code_description
10706                            .as_ref()
10707                            .and_then(|d| d.href.clone()),
10708                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10709                        markdown: adapter.as_ref().and_then(|adapter| {
10710                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10711                        }),
10712                        message: diagnostic.message.trim().to_string(),
10713                        group_id,
10714                        is_primary: true,
10715                        is_disk_based,
10716                        is_unnecessary,
10717                        underline,
10718                        data: diagnostic.data.clone(),
10719                    },
10720                });
10721                if let Some(infos) = &diagnostic.related_information {
10722                    for info in infos {
10723                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10724                            let range = range_from_lsp(info.location.range);
10725                            diagnostics.push(DiagnosticEntry {
10726                                range,
10727                                diagnostic: Diagnostic {
10728                                    source: diagnostic.source.clone(),
10729                                    source_kind,
10730                                    code: diagnostic.code.clone(),
10731                                    code_description: diagnostic
10732                                        .code_description
10733                                        .as_ref()
10734                                        .and_then(|d| d.href.clone()),
10735                                    severity: DiagnosticSeverity::INFORMATION,
10736                                    markdown: adapter.as_ref().and_then(|adapter| {
10737                                        adapter.diagnostic_message_to_markdown(&info.message)
10738                                    }),
10739                                    message: info.message.trim().to_string(),
10740                                    group_id,
10741                                    is_primary: false,
10742                                    is_disk_based,
10743                                    is_unnecessary: false,
10744                                    underline,
10745                                    data: diagnostic.data.clone(),
10746                                },
10747                            });
10748                        }
10749                    }
10750                }
10751            }
10752        }
10753
10754        for entry in &mut diagnostics {
10755            let diagnostic = &mut entry.diagnostic;
10756            if !diagnostic.is_primary {
10757                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10758                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10759                    source,
10760                    diagnostic.code.clone(),
10761                    entry.range.clone(),
10762                )) {
10763                    if let Some(severity) = severity {
10764                        diagnostic.severity = severity;
10765                    }
10766                    diagnostic.is_unnecessary = is_unnecessary;
10767                }
10768            }
10769        }
10770
10771        DocumentDiagnostics {
10772            diagnostics,
10773            document_abs_path,
10774            version: lsp_diagnostics.version,
10775        }
10776    }
10777
10778    fn insert_newly_running_language_server(
10779        &mut self,
10780        adapter: Arc<CachedLspAdapter>,
10781        language_server: Arc<LanguageServer>,
10782        server_id: LanguageServerId,
10783        key: LanguageServerSeed,
10784        workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
10785        cx: &mut Context<Self>,
10786    ) {
10787        let Some(local) = self.as_local_mut() else {
10788            return;
10789        };
10790        // If the language server for this key doesn't match the server id, don't store the
10791        // server. Which will cause it to be dropped, killing the process
10792        if local
10793            .language_server_ids
10794            .get(&key)
10795            .map(|state| state.id != server_id)
10796            .unwrap_or(false)
10797        {
10798            return;
10799        }
10800
10801        // Update language_servers collection with Running variant of LanguageServerState
10802        // indicating that the server is up and running and ready
10803        let workspace_folders = workspace_folders.lock().clone();
10804        language_server.set_workspace_folders(workspace_folders);
10805
10806        local.language_servers.insert(
10807            server_id,
10808            LanguageServerState::Running {
10809                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10810                    language_server.clone(),
10811                    cx,
10812                ),
10813                adapter: adapter.clone(),
10814                server: language_server.clone(),
10815                simulate_disk_based_diagnostics_completion: None,
10816            },
10817        );
10818        local
10819            .languages
10820            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10821        if let Some(file_ops_caps) = language_server
10822            .capabilities()
10823            .workspace
10824            .as_ref()
10825            .and_then(|ws| ws.file_operations.as_ref())
10826        {
10827            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10828            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10829            if did_rename_caps.or(will_rename_caps).is_some() {
10830                let watcher = RenamePathsWatchedForServer::default()
10831                    .with_did_rename_patterns(did_rename_caps)
10832                    .with_will_rename_patterns(will_rename_caps);
10833                local
10834                    .language_server_paths_watched_for_rename
10835                    .insert(server_id, watcher);
10836            }
10837        }
10838
10839        self.language_server_statuses.insert(
10840            server_id,
10841            LanguageServerStatus {
10842                name: language_server.name(),
10843                pending_work: Default::default(),
10844                has_pending_diagnostic_updates: false,
10845                progress_tokens: Default::default(),
10846            },
10847        );
10848
10849        cx.emit(LspStoreEvent::LanguageServerAdded(
10850            server_id,
10851            language_server.name(),
10852            Some(key.worktree_id),
10853        ));
10854        cx.emit(LspStoreEvent::RefreshInlayHints);
10855
10856        let server_capabilities = language_server.capabilities();
10857        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10858            downstream_client
10859                .send(proto::StartLanguageServer {
10860                    project_id: *project_id,
10861                    server: Some(proto::LanguageServer {
10862                        id: server_id.to_proto(),
10863                        name: language_server.name().to_string(),
10864                        worktree_id: Some(key.worktree_id.to_proto()),
10865                    }),
10866                    capabilities: serde_json::to_string(&server_capabilities)
10867                        .expect("serializing server LSP capabilities"),
10868                })
10869                .log_err();
10870        }
10871        self.lsp_server_capabilities
10872            .insert(server_id, server_capabilities);
10873
10874        // Tell the language server about every open buffer in the worktree that matches the language.
10875        // Also check for buffers in worktrees that reused this server
10876        let mut worktrees_using_server = vec![key.worktree_id];
10877        if let Some(local) = self.as_local() {
10878            // Find all worktrees that have this server in their language server tree
10879            for (worktree_id, servers) in &local.lsp_tree.instances {
10880                if *worktree_id != key.worktree_id {
10881                    for server_map in servers.roots.values() {
10882                        if server_map.contains_key(&key.name) {
10883                            worktrees_using_server.push(*worktree_id);
10884                        }
10885                    }
10886                }
10887            }
10888        }
10889
10890        let mut buffer_paths_registered = Vec::new();
10891        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10892            for buffer_handle in buffer_store.buffers() {
10893                let buffer = buffer_handle.read(cx);
10894                let file = match File::from_dyn(buffer.file()) {
10895                    Some(file) => file,
10896                    None => continue,
10897                };
10898                let language = match buffer.language() {
10899                    Some(language) => language,
10900                    None => continue,
10901                };
10902
10903                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10904                    || !self
10905                        .languages
10906                        .lsp_adapters(&language.name())
10907                        .iter()
10908                        .any(|a| a.name == key.name)
10909                {
10910                    continue;
10911                }
10912                // didOpen
10913                let file = match file.as_local() {
10914                    Some(file) => file,
10915                    None => continue,
10916                };
10917
10918                let local = self.as_local_mut().unwrap();
10919
10920                let buffer_id = buffer.remote_id();
10921                if local.registered_buffers.contains_key(&buffer_id) {
10922                    let versions = local
10923                        .buffer_snapshots
10924                        .entry(buffer_id)
10925                        .or_default()
10926                        .entry(server_id)
10927                        .and_modify(|_| {
10928                            assert!(
10929                            false,
10930                            "There should not be an existing snapshot for a newly inserted buffer"
10931                        )
10932                        })
10933                        .or_insert_with(|| {
10934                            vec![LspBufferSnapshot {
10935                                version: 0,
10936                                snapshot: buffer.text_snapshot(),
10937                            }]
10938                        });
10939
10940                    let snapshot = versions.last().unwrap();
10941                    let version = snapshot.version;
10942                    let initial_snapshot = &snapshot.snapshot;
10943                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
10944                    language_server.register_buffer(
10945                        uri,
10946                        adapter.language_id(&language.name()),
10947                        version,
10948                        initial_snapshot.text(),
10949                    );
10950                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10951                    local
10952                        .buffers_opened_in_servers
10953                        .entry(buffer_id)
10954                        .or_default()
10955                        .insert(server_id);
10956                }
10957                buffer_handle.update(cx, |buffer, cx| {
10958                    buffer.set_completion_triggers(
10959                        server_id,
10960                        language_server
10961                            .capabilities()
10962                            .completion_provider
10963                            .as_ref()
10964                            .and_then(|provider| {
10965                                provider
10966                                    .trigger_characters
10967                                    .as_ref()
10968                                    .map(|characters| characters.iter().cloned().collect())
10969                            })
10970                            .unwrap_or_default(),
10971                        cx,
10972                    )
10973                });
10974            }
10975        });
10976
10977        for (buffer_id, abs_path) in buffer_paths_registered {
10978            cx.emit(LspStoreEvent::LanguageServerUpdate {
10979                language_server_id: server_id,
10980                name: Some(adapter.name()),
10981                message: proto::update_language_server::Variant::RegisteredForBuffer(
10982                    proto::RegisteredForBuffer {
10983                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
10984                        buffer_id: buffer_id.to_proto(),
10985                    },
10986                ),
10987            });
10988        }
10989
10990        cx.notify();
10991    }
10992
10993    pub fn language_servers_running_disk_based_diagnostics(
10994        &self,
10995    ) -> impl Iterator<Item = LanguageServerId> + '_ {
10996        self.language_server_statuses
10997            .iter()
10998            .filter_map(|(id, status)| {
10999                if status.has_pending_diagnostic_updates {
11000                    Some(*id)
11001                } else {
11002                    None
11003                }
11004            })
11005    }
11006
11007    pub(crate) fn cancel_language_server_work_for_buffers(
11008        &mut self,
11009        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11010        cx: &mut Context<Self>,
11011    ) {
11012        if let Some((client, project_id)) = self.upstream_client() {
11013            let request = client.request(proto::CancelLanguageServerWork {
11014                project_id,
11015                work: Some(proto::cancel_language_server_work::Work::Buffers(
11016                    proto::cancel_language_server_work::Buffers {
11017                        buffer_ids: buffers
11018                            .into_iter()
11019                            .map(|b| b.read(cx).remote_id().to_proto())
11020                            .collect(),
11021                    },
11022                )),
11023            });
11024            cx.background_spawn(request).detach_and_log_err(cx);
11025        } else if let Some(local) = self.as_local() {
11026            let servers = buffers
11027                .into_iter()
11028                .flat_map(|buffer| {
11029                    buffer.update(cx, |buffer, cx| {
11030                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11031                    })
11032                })
11033                .collect::<HashSet<_>>();
11034            for server_id in servers {
11035                self.cancel_language_server_work(server_id, None, cx);
11036            }
11037        }
11038    }
11039
11040    pub(crate) fn cancel_language_server_work(
11041        &mut self,
11042        server_id: LanguageServerId,
11043        token_to_cancel: Option<String>,
11044        cx: &mut Context<Self>,
11045    ) {
11046        if let Some(local) = self.as_local() {
11047            let status = self.language_server_statuses.get(&server_id);
11048            let server = local.language_servers.get(&server_id);
11049            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11050            {
11051                for (token, progress) in &status.pending_work {
11052                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11053                        && token != token_to_cancel
11054                    {
11055                        continue;
11056                    }
11057                    if progress.is_cancellable {
11058                        server
11059                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11060                                &WorkDoneProgressCancelParams {
11061                                    token: lsp::NumberOrString::String(token.clone()),
11062                                },
11063                            )
11064                            .ok();
11065                    }
11066                }
11067            }
11068        } else if let Some((client, project_id)) = self.upstream_client() {
11069            let request = client.request(proto::CancelLanguageServerWork {
11070                project_id,
11071                work: Some(
11072                    proto::cancel_language_server_work::Work::LanguageServerWork(
11073                        proto::cancel_language_server_work::LanguageServerWork {
11074                            language_server_id: server_id.to_proto(),
11075                            token: token_to_cancel,
11076                        },
11077                    ),
11078                ),
11079            });
11080            cx.background_spawn(request).detach_and_log_err(cx);
11081        }
11082    }
11083
11084    fn register_supplementary_language_server(
11085        &mut self,
11086        id: LanguageServerId,
11087        name: LanguageServerName,
11088        server: Arc<LanguageServer>,
11089        cx: &mut Context<Self>,
11090    ) {
11091        if let Some(local) = self.as_local_mut() {
11092            local
11093                .supplementary_language_servers
11094                .insert(id, (name.clone(), server));
11095            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11096        }
11097    }
11098
11099    fn unregister_supplementary_language_server(
11100        &mut self,
11101        id: LanguageServerId,
11102        cx: &mut Context<Self>,
11103    ) {
11104        if let Some(local) = self.as_local_mut() {
11105            local.supplementary_language_servers.remove(&id);
11106            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11107        }
11108    }
11109
11110    pub(crate) fn supplementary_language_servers(
11111        &self,
11112    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11113        self.as_local().into_iter().flat_map(|local| {
11114            local
11115                .supplementary_language_servers
11116                .iter()
11117                .map(|(id, (name, _))| (*id, name.clone()))
11118        })
11119    }
11120
11121    pub fn language_server_adapter_for_id(
11122        &self,
11123        id: LanguageServerId,
11124    ) -> Option<Arc<CachedLspAdapter>> {
11125        self.as_local()
11126            .and_then(|local| local.language_servers.get(&id))
11127            .and_then(|language_server_state| match language_server_state {
11128                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11129                _ => None,
11130            })
11131    }
11132
11133    pub(super) fn update_local_worktree_language_servers(
11134        &mut self,
11135        worktree_handle: &Entity<Worktree>,
11136        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
11137        cx: &mut Context<Self>,
11138    ) {
11139        if changes.is_empty() {
11140            return;
11141        }
11142
11143        let Some(local) = self.as_local() else { return };
11144
11145        local.prettier_store.update(cx, |prettier_store, cx| {
11146            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11147        });
11148
11149        let worktree_id = worktree_handle.read(cx).id();
11150        let mut language_server_ids = local
11151            .language_server_ids
11152            .iter()
11153            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11154            .collect::<Vec<_>>();
11155        language_server_ids.sort();
11156        language_server_ids.dedup();
11157
11158        let abs_path = worktree_handle.read(cx).abs_path();
11159        for server_id in &language_server_ids {
11160            if let Some(LanguageServerState::Running { server, .. }) =
11161                local.language_servers.get(server_id)
11162                && let Some(watched_paths) = local
11163                    .language_server_watched_paths
11164                    .get(server_id)
11165                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11166            {
11167                let params = lsp::DidChangeWatchedFilesParams {
11168                    changes: changes
11169                        .iter()
11170                        .filter_map(|(path, _, change)| {
11171                            if !watched_paths.is_match(path) {
11172                                return None;
11173                            }
11174                            let typ = match change {
11175                                PathChange::Loaded => return None,
11176                                PathChange::Added => lsp::FileChangeType::CREATED,
11177                                PathChange::Removed => lsp::FileChangeType::DELETED,
11178                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11179                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11180                            };
11181                            Some(lsp::FileEvent {
11182                                uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
11183                                typ,
11184                            })
11185                        })
11186                        .collect(),
11187                };
11188                if !params.changes.is_empty() {
11189                    server
11190                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
11191                        .ok();
11192                }
11193            }
11194        }
11195        for (path, _, _) in changes {
11196            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
11197                && local.watched_manifest_filenames.contains(file_name)
11198            {
11199                self.request_workspace_config_refresh();
11200                break;
11201            }
11202        }
11203    }
11204
11205    pub fn wait_for_remote_buffer(
11206        &mut self,
11207        id: BufferId,
11208        cx: &mut Context<Self>,
11209    ) -> Task<Result<Entity<Buffer>>> {
11210        self.buffer_store.update(cx, |buffer_store, cx| {
11211            buffer_store.wait_for_remote_buffer(id, cx)
11212        })
11213    }
11214
11215    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11216        proto::Symbol {
11217            language_server_name: symbol.language_server_name.0.to_string(),
11218            source_worktree_id: symbol.source_worktree_id.to_proto(),
11219            language_server_id: symbol.source_language_server_id.to_proto(),
11220            worktree_id: symbol.path.worktree_id.to_proto(),
11221            path: symbol.path.path.as_ref().to_proto(),
11222            name: symbol.name.clone(),
11223            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11224            start: Some(proto::PointUtf16 {
11225                row: symbol.range.start.0.row,
11226                column: symbol.range.start.0.column,
11227            }),
11228            end: Some(proto::PointUtf16 {
11229                row: symbol.range.end.0.row,
11230                column: symbol.range.end.0.column,
11231            }),
11232            signature: symbol.signature.to_vec(),
11233        }
11234    }
11235
11236    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11237        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11238        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11239        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11240        let path = ProjectPath {
11241            worktree_id,
11242            path: Arc::<Path>::from_proto(serialized_symbol.path),
11243        };
11244
11245        let start = serialized_symbol.start.context("invalid start")?;
11246        let end = serialized_symbol.end.context("invalid end")?;
11247        Ok(CoreSymbol {
11248            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11249            source_worktree_id,
11250            source_language_server_id: LanguageServerId::from_proto(
11251                serialized_symbol.language_server_id,
11252            ),
11253            path,
11254            name: serialized_symbol.name,
11255            range: Unclipped(PointUtf16::new(start.row, start.column))
11256                ..Unclipped(PointUtf16::new(end.row, end.column)),
11257            kind,
11258            signature: serialized_symbol
11259                .signature
11260                .try_into()
11261                .map_err(|_| anyhow!("invalid signature"))?,
11262        })
11263    }
11264
11265    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11266        let mut serialized_completion = proto::Completion {
11267            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11268            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11269            new_text: completion.new_text.clone(),
11270            ..proto::Completion::default()
11271        };
11272        match &completion.source {
11273            CompletionSource::Lsp {
11274                insert_range,
11275                server_id,
11276                lsp_completion,
11277                lsp_defaults,
11278                resolved,
11279            } => {
11280                let (old_insert_start, old_insert_end) = insert_range
11281                    .as_ref()
11282                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11283                    .unzip();
11284
11285                serialized_completion.old_insert_start = old_insert_start;
11286                serialized_completion.old_insert_end = old_insert_end;
11287                serialized_completion.source = proto::completion::Source::Lsp as i32;
11288                serialized_completion.server_id = server_id.0 as u64;
11289                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11290                serialized_completion.lsp_defaults = lsp_defaults
11291                    .as_deref()
11292                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11293                serialized_completion.resolved = *resolved;
11294            }
11295            CompletionSource::BufferWord {
11296                word_range,
11297                resolved,
11298            } => {
11299                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11300                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11301                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11302                serialized_completion.resolved = *resolved;
11303            }
11304            CompletionSource::Custom => {
11305                serialized_completion.source = proto::completion::Source::Custom as i32;
11306                serialized_completion.resolved = true;
11307            }
11308            CompletionSource::Dap { sort_text } => {
11309                serialized_completion.source = proto::completion::Source::Dap as i32;
11310                serialized_completion.sort_text = Some(sort_text.clone());
11311            }
11312        }
11313
11314        serialized_completion
11315    }
11316
11317    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11318        let old_replace_start = completion
11319            .old_replace_start
11320            .and_then(deserialize_anchor)
11321            .context("invalid old start")?;
11322        let old_replace_end = completion
11323            .old_replace_end
11324            .and_then(deserialize_anchor)
11325            .context("invalid old end")?;
11326        let insert_range = {
11327            match completion.old_insert_start.zip(completion.old_insert_end) {
11328                Some((start, end)) => {
11329                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11330                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11331                    Some(start..end)
11332                }
11333                None => None,
11334            }
11335        };
11336        Ok(CoreCompletion {
11337            replace_range: old_replace_start..old_replace_end,
11338            new_text: completion.new_text,
11339            source: match proto::completion::Source::from_i32(completion.source) {
11340                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11341                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11342                    insert_range,
11343                    server_id: LanguageServerId::from_proto(completion.server_id),
11344                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11345                    lsp_defaults: completion
11346                        .lsp_defaults
11347                        .as_deref()
11348                        .map(serde_json::from_slice)
11349                        .transpose()?,
11350                    resolved: completion.resolved,
11351                },
11352                Some(proto::completion::Source::BufferWord) => {
11353                    let word_range = completion
11354                        .buffer_word_start
11355                        .and_then(deserialize_anchor)
11356                        .context("invalid buffer word start")?
11357                        ..completion
11358                            .buffer_word_end
11359                            .and_then(deserialize_anchor)
11360                            .context("invalid buffer word end")?;
11361                    CompletionSource::BufferWord {
11362                        word_range,
11363                        resolved: completion.resolved,
11364                    }
11365                }
11366                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11367                    sort_text: completion
11368                        .sort_text
11369                        .context("expected sort text to exist")?,
11370                },
11371                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11372            },
11373        })
11374    }
11375
11376    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11377        let (kind, lsp_action) = match &action.lsp_action {
11378            LspAction::Action(code_action) => (
11379                proto::code_action::Kind::Action as i32,
11380                serde_json::to_vec(code_action).unwrap(),
11381            ),
11382            LspAction::Command(command) => (
11383                proto::code_action::Kind::Command as i32,
11384                serde_json::to_vec(command).unwrap(),
11385            ),
11386            LspAction::CodeLens(code_lens) => (
11387                proto::code_action::Kind::CodeLens as i32,
11388                serde_json::to_vec(code_lens).unwrap(),
11389            ),
11390        };
11391
11392        proto::CodeAction {
11393            server_id: action.server_id.0 as u64,
11394            start: Some(serialize_anchor(&action.range.start)),
11395            end: Some(serialize_anchor(&action.range.end)),
11396            lsp_action,
11397            kind,
11398            resolved: action.resolved,
11399        }
11400    }
11401
11402    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11403        let start = action
11404            .start
11405            .and_then(deserialize_anchor)
11406            .context("invalid start")?;
11407        let end = action
11408            .end
11409            .and_then(deserialize_anchor)
11410            .context("invalid end")?;
11411        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11412            Some(proto::code_action::Kind::Action) => {
11413                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11414            }
11415            Some(proto::code_action::Kind::Command) => {
11416                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11417            }
11418            Some(proto::code_action::Kind::CodeLens) => {
11419                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11420            }
11421            None => anyhow::bail!("Unknown action kind {}", action.kind),
11422        };
11423        Ok(CodeAction {
11424            server_id: LanguageServerId(action.server_id as usize),
11425            range: start..end,
11426            resolved: action.resolved,
11427            lsp_action,
11428        })
11429    }
11430
11431    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11432        match &formatting_result {
11433            Ok(_) => self.last_formatting_failure = None,
11434            Err(error) => {
11435                let error_string = format!("{error:#}");
11436                log::error!("Formatting failed: {error_string}");
11437                self.last_formatting_failure
11438                    .replace(error_string.lines().join(" "));
11439            }
11440        }
11441    }
11442
11443    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11444        self.lsp_server_capabilities.remove(&for_server);
11445        for buffer_colors in self.lsp_document_colors.values_mut() {
11446            buffer_colors.colors.remove(&for_server);
11447            buffer_colors.cache_version += 1;
11448        }
11449        for buffer_lens in self.lsp_code_lens.values_mut() {
11450            buffer_lens.lens.remove(&for_server);
11451        }
11452        if let Some(local) = self.as_local_mut() {
11453            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11454            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11455                buffer_servers.remove(&for_server);
11456            }
11457        }
11458    }
11459
11460    pub fn result_id(
11461        &self,
11462        server_id: LanguageServerId,
11463        buffer_id: BufferId,
11464        cx: &App,
11465    ) -> Option<String> {
11466        let abs_path = self
11467            .buffer_store
11468            .read(cx)
11469            .get(buffer_id)
11470            .and_then(|b| File::from_dyn(b.read(cx).file()))
11471            .map(|f| f.abs_path(cx))?;
11472        self.as_local()?
11473            .buffer_pull_diagnostics_result_ids
11474            .get(&server_id)?
11475            .get(&abs_path)?
11476            .clone()
11477    }
11478
11479    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11480        let Some(local) = self.as_local() else {
11481            return HashMap::default();
11482        };
11483        local
11484            .buffer_pull_diagnostics_result_ids
11485            .get(&server_id)
11486            .into_iter()
11487            .flatten()
11488            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11489            .collect()
11490    }
11491
11492    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11493        if let Some(LanguageServerState::Running {
11494            workspace_refresh_task: Some(workspace_refresh_task),
11495            ..
11496        }) = self
11497            .as_local_mut()
11498            .and_then(|local| local.language_servers.get_mut(&server_id))
11499        {
11500            workspace_refresh_task.refresh_tx.try_send(()).ok();
11501        }
11502    }
11503
11504    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11505        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11506            return;
11507        };
11508        let Some(local) = self.as_local_mut() else {
11509            return;
11510        };
11511
11512        for server_id in buffer.update(cx, |buffer, cx| {
11513            local.language_server_ids_for_buffer(buffer, cx)
11514        }) {
11515            if let Some(LanguageServerState::Running {
11516                workspace_refresh_task: Some(workspace_refresh_task),
11517                ..
11518            }) = local.language_servers.get_mut(&server_id)
11519            {
11520                workspace_refresh_task.refresh_tx.try_send(()).ok();
11521            }
11522        }
11523    }
11524
11525    fn apply_workspace_diagnostic_report(
11526        &mut self,
11527        server_id: LanguageServerId,
11528        report: lsp::WorkspaceDiagnosticReportResult,
11529        cx: &mut Context<Self>,
11530    ) {
11531        let workspace_diagnostics =
11532            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11533        let mut unchanged_buffers = HashSet::default();
11534        let mut changed_buffers = HashSet::default();
11535        let workspace_diagnostics_updates = workspace_diagnostics
11536            .into_iter()
11537            .filter_map(
11538                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11539                    LspPullDiagnostics::Response {
11540                        server_id,
11541                        uri,
11542                        diagnostics,
11543                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11544                    LspPullDiagnostics::Default => None,
11545                },
11546            )
11547            .fold(
11548                HashMap::default(),
11549                |mut acc, (server_id, uri, diagnostics, version)| {
11550                    let (result_id, diagnostics) = match diagnostics {
11551                        PulledDiagnostics::Unchanged { result_id } => {
11552                            unchanged_buffers.insert(uri.clone());
11553                            (Some(result_id), Vec::new())
11554                        }
11555                        PulledDiagnostics::Changed {
11556                            result_id,
11557                            diagnostics,
11558                        } => {
11559                            changed_buffers.insert(uri.clone());
11560                            (result_id, diagnostics)
11561                        }
11562                    };
11563                    let disk_based_sources = Cow::Owned(
11564                        self.language_server_adapter_for_id(server_id)
11565                            .as_ref()
11566                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11567                            .unwrap_or(&[])
11568                            .to_vec(),
11569                    );
11570                    acc.entry(server_id)
11571                        .or_insert_with(Vec::new)
11572                        .push(DocumentDiagnosticsUpdate {
11573                            server_id,
11574                            diagnostics: lsp::PublishDiagnosticsParams {
11575                                uri,
11576                                diagnostics,
11577                                version,
11578                            },
11579                            result_id,
11580                            disk_based_sources,
11581                        });
11582                    acc
11583                },
11584            );
11585
11586        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11587            self.merge_lsp_diagnostics(
11588                DiagnosticSourceKind::Pulled,
11589                diagnostic_updates,
11590                |buffer, old_diagnostic, cx| {
11591                    File::from_dyn(buffer.file())
11592                        .and_then(|file| {
11593                            let abs_path = file.as_local()?.abs_path(cx);
11594                            lsp::Url::from_file_path(abs_path).ok()
11595                        })
11596                        .is_none_or(|buffer_uri| {
11597                            unchanged_buffers.contains(&buffer_uri)
11598                                || match old_diagnostic.source_kind {
11599                                    DiagnosticSourceKind::Pulled => {
11600                                        !changed_buffers.contains(&buffer_uri)
11601                                    }
11602                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11603                                        true
11604                                    }
11605                                }
11606                        })
11607                },
11608                cx,
11609            )
11610            .log_err();
11611        }
11612    }
11613
11614    fn register_server_capabilities(
11615        &mut self,
11616        server_id: LanguageServerId,
11617        params: lsp::RegistrationParams,
11618        cx: &mut Context<Self>,
11619    ) -> anyhow::Result<()> {
11620        let server = self
11621            .language_server_for_id(server_id)
11622            .with_context(|| format!("no server {server_id} found"))?;
11623        for reg in params.registrations {
11624            match reg.method.as_str() {
11625                "workspace/didChangeWatchedFiles" => {
11626                    if let Some(options) = reg.register_options {
11627                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11628                            let caps = serde_json::from_value(options)?;
11629                            local_lsp_store
11630                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11631                            true
11632                        } else {
11633                            false
11634                        };
11635                        if notify {
11636                            notify_server_capabilities_updated(&server, cx);
11637                        }
11638                    }
11639                }
11640                "workspace/didChangeConfiguration" => {
11641                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11642                }
11643                "workspace/symbol" => {
11644                    if let Some(options) = parse_register_capabilities(reg)? {
11645                        server.update_capabilities(|capabilities| {
11646                            capabilities.workspace_symbol_provider = Some(options);
11647                        });
11648                        notify_server_capabilities_updated(&server, cx);
11649                    }
11650                }
11651                "workspace/fileOperations" => {
11652                    if let Some(options) = reg.register_options {
11653                        let caps = serde_json::from_value(options)?;
11654                        server.update_capabilities(|capabilities| {
11655                            capabilities
11656                                .workspace
11657                                .get_or_insert_default()
11658                                .file_operations = Some(caps);
11659                        });
11660                        notify_server_capabilities_updated(&server, cx);
11661                    }
11662                }
11663                "workspace/executeCommand" => {
11664                    if let Some(options) = reg.register_options {
11665                        let options = serde_json::from_value(options)?;
11666                        server.update_capabilities(|capabilities| {
11667                            capabilities.execute_command_provider = Some(options);
11668                        });
11669                        notify_server_capabilities_updated(&server, cx);
11670                    }
11671                }
11672                "textDocument/rangeFormatting" => {
11673                    if let Some(options) = parse_register_capabilities(reg)? {
11674                        server.update_capabilities(|capabilities| {
11675                            capabilities.document_range_formatting_provider = Some(options);
11676                        });
11677                        notify_server_capabilities_updated(&server, cx);
11678                    }
11679                }
11680                "textDocument/onTypeFormatting" => {
11681                    if let Some(options) = reg
11682                        .register_options
11683                        .map(serde_json::from_value)
11684                        .transpose()?
11685                    {
11686                        server.update_capabilities(|capabilities| {
11687                            capabilities.document_on_type_formatting_provider = Some(options);
11688                        });
11689                        notify_server_capabilities_updated(&server, cx);
11690                    }
11691                }
11692                "textDocument/formatting" => {
11693                    if let Some(options) = parse_register_capabilities(reg)? {
11694                        server.update_capabilities(|capabilities| {
11695                            capabilities.document_formatting_provider = Some(options);
11696                        });
11697                        notify_server_capabilities_updated(&server, cx);
11698                    }
11699                }
11700                "textDocument/rename" => {
11701                    if let Some(options) = parse_register_capabilities(reg)? {
11702                        server.update_capabilities(|capabilities| {
11703                            capabilities.rename_provider = Some(options);
11704                        });
11705                        notify_server_capabilities_updated(&server, cx);
11706                    }
11707                }
11708                "textDocument/inlayHint" => {
11709                    if let Some(options) = parse_register_capabilities(reg)? {
11710                        server.update_capabilities(|capabilities| {
11711                            capabilities.inlay_hint_provider = Some(options);
11712                        });
11713                        notify_server_capabilities_updated(&server, cx);
11714                    }
11715                }
11716                "textDocument/documentSymbol" => {
11717                    if let Some(options) = parse_register_capabilities(reg)? {
11718                        server.update_capabilities(|capabilities| {
11719                            capabilities.document_symbol_provider = Some(options);
11720                        });
11721                        notify_server_capabilities_updated(&server, cx);
11722                    }
11723                }
11724                "textDocument/codeAction" => {
11725                    if let Some(options) = reg
11726                        .register_options
11727                        .map(serde_json::from_value)
11728                        .transpose()?
11729                    {
11730                        server.update_capabilities(|capabilities| {
11731                            capabilities.code_action_provider =
11732                                Some(lsp::CodeActionProviderCapability::Options(options));
11733                        });
11734                        notify_server_capabilities_updated(&server, cx);
11735                    }
11736                }
11737                "textDocument/definition" => {
11738                    if let Some(options) = parse_register_capabilities(reg)? {
11739                        server.update_capabilities(|capabilities| {
11740                            capabilities.definition_provider = Some(options);
11741                        });
11742                        notify_server_capabilities_updated(&server, cx);
11743                    }
11744                }
11745                "textDocument/completion" => {
11746                    if let Some(caps) = reg
11747                        .register_options
11748                        .map(serde_json::from_value)
11749                        .transpose()?
11750                    {
11751                        server.update_capabilities(|capabilities| {
11752                            capabilities.completion_provider = Some(caps);
11753                        });
11754                        notify_server_capabilities_updated(&server, cx);
11755                    }
11756                }
11757                "textDocument/hover" => {
11758                    if let Some(caps) = reg
11759                        .register_options
11760                        .map(serde_json::from_value)
11761                        .transpose()?
11762                    {
11763                        server.update_capabilities(|capabilities| {
11764                            capabilities.hover_provider = Some(caps);
11765                        });
11766                        notify_server_capabilities_updated(&server, cx);
11767                    }
11768                }
11769                "textDocument/signatureHelp" => {
11770                    if let Some(caps) = reg
11771                        .register_options
11772                        .map(serde_json::from_value)
11773                        .transpose()?
11774                    {
11775                        server.update_capabilities(|capabilities| {
11776                            capabilities.signature_help_provider = Some(caps);
11777                        });
11778                        notify_server_capabilities_updated(&server, cx);
11779                    }
11780                }
11781                "textDocument/didChange" => {
11782                    if let Some(sync_kind) = reg
11783                        .register_options
11784                        .and_then(|opts| opts.get("syncKind").cloned())
11785                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11786                        .transpose()?
11787                    {
11788                        server.update_capabilities(|capabilities| {
11789                            let mut sync_options =
11790                                Self::take_text_document_sync_options(capabilities);
11791                            sync_options.change = Some(sync_kind);
11792                            capabilities.text_document_sync =
11793                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11794                        });
11795                        notify_server_capabilities_updated(&server, cx);
11796                    }
11797                }
11798                "textDocument/didSave" => {
11799                    if let Some(include_text) = reg
11800                        .register_options
11801                        .map(|opts| {
11802                            let transpose = opts
11803                                .get("includeText")
11804                                .cloned()
11805                                .map(serde_json::from_value::<Option<bool>>)
11806                                .transpose();
11807                            match transpose {
11808                                Ok(value) => Ok(value.flatten()),
11809                                Err(e) => Err(e),
11810                            }
11811                        })
11812                        .transpose()?
11813                    {
11814                        server.update_capabilities(|capabilities| {
11815                            let mut sync_options =
11816                                Self::take_text_document_sync_options(capabilities);
11817                            sync_options.save =
11818                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11819                                    include_text,
11820                                }));
11821                            capabilities.text_document_sync =
11822                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11823                        });
11824                        notify_server_capabilities_updated(&server, cx);
11825                    }
11826                }
11827                "textDocument/codeLens" => {
11828                    if let Some(caps) = reg
11829                        .register_options
11830                        .map(serde_json::from_value)
11831                        .transpose()?
11832                    {
11833                        server.update_capabilities(|capabilities| {
11834                            capabilities.code_lens_provider = Some(caps);
11835                        });
11836                        notify_server_capabilities_updated(&server, cx);
11837                    }
11838                }
11839                "textDocument/diagnostic" => {
11840                    if let Some(caps) = reg
11841                        .register_options
11842                        .map(serde_json::from_value)
11843                        .transpose()?
11844                    {
11845                        server.update_capabilities(|capabilities| {
11846                            capabilities.diagnostic_provider = Some(caps);
11847                        });
11848                        notify_server_capabilities_updated(&server, cx);
11849                    }
11850                }
11851                "textDocument/colorProvider" => {
11852                    if let Some(caps) = reg
11853                        .register_options
11854                        .map(serde_json::from_value)
11855                        .transpose()?
11856                    {
11857                        server.update_capabilities(|capabilities| {
11858                            capabilities.color_provider = Some(caps);
11859                        });
11860                        notify_server_capabilities_updated(&server, cx);
11861                    }
11862                }
11863                _ => log::warn!("unhandled capability registration: {reg:?}"),
11864            }
11865        }
11866
11867        Ok(())
11868    }
11869
11870    fn unregister_server_capabilities(
11871        &mut self,
11872        server_id: LanguageServerId,
11873        params: lsp::UnregistrationParams,
11874        cx: &mut Context<Self>,
11875    ) -> anyhow::Result<()> {
11876        let server = self
11877            .language_server_for_id(server_id)
11878            .with_context(|| format!("no server {server_id} found"))?;
11879        for unreg in params.unregisterations.iter() {
11880            match unreg.method.as_str() {
11881                "workspace/didChangeWatchedFiles" => {
11882                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11883                        local_lsp_store
11884                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11885                        true
11886                    } else {
11887                        false
11888                    };
11889                    if notify {
11890                        notify_server_capabilities_updated(&server, cx);
11891                    }
11892                }
11893                "workspace/didChangeConfiguration" => {
11894                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11895                }
11896                "workspace/symbol" => {
11897                    server.update_capabilities(|capabilities| {
11898                        capabilities.workspace_symbol_provider = None
11899                    });
11900                    notify_server_capabilities_updated(&server, cx);
11901                }
11902                "workspace/fileOperations" => {
11903                    server.update_capabilities(|capabilities| {
11904                        capabilities
11905                            .workspace
11906                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11907                                workspace_folders: None,
11908                                file_operations: None,
11909                            })
11910                            .file_operations = None;
11911                    });
11912                    notify_server_capabilities_updated(&server, cx);
11913                }
11914                "workspace/executeCommand" => {
11915                    server.update_capabilities(|capabilities| {
11916                        capabilities.execute_command_provider = None;
11917                    });
11918                    notify_server_capabilities_updated(&server, cx);
11919                }
11920                "textDocument/rangeFormatting" => {
11921                    server.update_capabilities(|capabilities| {
11922                        capabilities.document_range_formatting_provider = None
11923                    });
11924                    notify_server_capabilities_updated(&server, cx);
11925                }
11926                "textDocument/onTypeFormatting" => {
11927                    server.update_capabilities(|capabilities| {
11928                        capabilities.document_on_type_formatting_provider = None;
11929                    });
11930                    notify_server_capabilities_updated(&server, cx);
11931                }
11932                "textDocument/formatting" => {
11933                    server.update_capabilities(|capabilities| {
11934                        capabilities.document_formatting_provider = None;
11935                    });
11936                    notify_server_capabilities_updated(&server, cx);
11937                }
11938                "textDocument/rename" => {
11939                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11940                    notify_server_capabilities_updated(&server, cx);
11941                }
11942                "textDocument/codeAction" => {
11943                    server.update_capabilities(|capabilities| {
11944                        capabilities.code_action_provider = None;
11945                    });
11946                    notify_server_capabilities_updated(&server, cx);
11947                }
11948                "textDocument/definition" => {
11949                    server.update_capabilities(|capabilities| {
11950                        capabilities.definition_provider = None;
11951                    });
11952                    notify_server_capabilities_updated(&server, cx);
11953                }
11954                "textDocument/completion" => {
11955                    server.update_capabilities(|capabilities| {
11956                        capabilities.completion_provider = None;
11957                    });
11958                    notify_server_capabilities_updated(&server, cx);
11959                }
11960                "textDocument/hover" => {
11961                    server.update_capabilities(|capabilities| {
11962                        capabilities.hover_provider = None;
11963                    });
11964                    notify_server_capabilities_updated(&server, cx);
11965                }
11966                "textDocument/signatureHelp" => {
11967                    server.update_capabilities(|capabilities| {
11968                        capabilities.signature_help_provider = None;
11969                    });
11970                    notify_server_capabilities_updated(&server, cx);
11971                }
11972                "textDocument/didChange" => {
11973                    server.update_capabilities(|capabilities| {
11974                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11975                        sync_options.change = None;
11976                        capabilities.text_document_sync =
11977                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11978                    });
11979                    notify_server_capabilities_updated(&server, cx);
11980                }
11981                "textDocument/didSave" => {
11982                    server.update_capabilities(|capabilities| {
11983                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11984                        sync_options.save = None;
11985                        capabilities.text_document_sync =
11986                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11987                    });
11988                    notify_server_capabilities_updated(&server, cx);
11989                }
11990                "textDocument/codeLens" => {
11991                    server.update_capabilities(|capabilities| {
11992                        capabilities.code_lens_provider = None;
11993                    });
11994                    notify_server_capabilities_updated(&server, cx);
11995                }
11996                "textDocument/diagnostic" => {
11997                    server.update_capabilities(|capabilities| {
11998                        capabilities.diagnostic_provider = None;
11999                    });
12000                    notify_server_capabilities_updated(&server, cx);
12001                }
12002                "textDocument/colorProvider" => {
12003                    server.update_capabilities(|capabilities| {
12004                        capabilities.color_provider = None;
12005                    });
12006                    notify_server_capabilities_updated(&server, cx);
12007                }
12008                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12009            }
12010        }
12011
12012        Ok(())
12013    }
12014
12015    fn take_text_document_sync_options(
12016        capabilities: &mut lsp::ServerCapabilities,
12017    ) -> lsp::TextDocumentSyncOptions {
12018        match capabilities.text_document_sync.take() {
12019            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12020            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12021                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12022                sync_options.change = Some(sync_kind);
12023                sync_options
12024            }
12025            None => lsp::TextDocumentSyncOptions::default(),
12026        }
12027    }
12028}
12029
12030// Registration with registerOptions as null, should fallback to true.
12031// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12032fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12033    reg: lsp::Registration,
12034) -> anyhow::Result<Option<OneOf<bool, T>>> {
12035    Ok(match reg.register_options {
12036        Some(options) => Some(OneOf::Right(serde_json::from_value::<T>(options)?)),
12037        None => Some(OneOf::Left(true)),
12038    })
12039}
12040
12041fn subscribe_to_binary_statuses(
12042    languages: &Arc<LanguageRegistry>,
12043    cx: &mut Context<'_, LspStore>,
12044) -> Task<()> {
12045    let mut server_statuses = languages.language_server_binary_statuses();
12046    cx.spawn(async move |lsp_store, cx| {
12047        while let Some((server_name, binary_status)) = server_statuses.next().await {
12048            if lsp_store
12049                .update(cx, |_, cx| {
12050                    let mut message = None;
12051                    let binary_status = match binary_status {
12052                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12053                        BinaryStatus::CheckingForUpdate => {
12054                            proto::ServerBinaryStatus::CheckingForUpdate
12055                        }
12056                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12057                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12058                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12059                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12060                        BinaryStatus::Failed { error } => {
12061                            message = Some(error);
12062                            proto::ServerBinaryStatus::Failed
12063                        }
12064                    };
12065                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12066                        // Binary updates are about the binary that might not have any language server id at that point.
12067                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12068                        language_server_id: LanguageServerId(0),
12069                        name: Some(server_name),
12070                        message: proto::update_language_server::Variant::StatusUpdate(
12071                            proto::StatusUpdate {
12072                                message,
12073                                status: Some(proto::status_update::Status::Binary(
12074                                    binary_status as i32,
12075                                )),
12076                            },
12077                        ),
12078                    });
12079                })
12080                .is_err()
12081            {
12082                break;
12083            }
12084        }
12085    })
12086}
12087
12088fn lsp_workspace_diagnostics_refresh(
12089    server: Arc<LanguageServer>,
12090    cx: &mut Context<'_, LspStore>,
12091) -> Option<WorkspaceRefreshTask> {
12092    let identifier = match server.capabilities().diagnostic_provider? {
12093        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12094            if !diagnostic_options.workspace_diagnostics {
12095                return None;
12096            }
12097            diagnostic_options.identifier
12098        }
12099        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12100            let diagnostic_options = registration_options.diagnostic_options;
12101            if !diagnostic_options.workspace_diagnostics {
12102                return None;
12103            }
12104            diagnostic_options.identifier
12105        }
12106    };
12107
12108    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12109    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12110    refresh_tx.try_send(()).ok();
12111
12112    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12113        let mut attempts = 0;
12114        let max_attempts = 50;
12115        let mut requests = 0;
12116
12117        loop {
12118            let Some(()) = refresh_rx.recv().await else {
12119                return;
12120            };
12121
12122            'request: loop {
12123                requests += 1;
12124                if attempts > max_attempts {
12125                    log::error!(
12126                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12127                    );
12128                    return;
12129                }
12130                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12131                cx.background_executor()
12132                    .timer(Duration::from_millis(backoff_millis))
12133                    .await;
12134                attempts += 1;
12135
12136                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12137                    lsp_store
12138                        .all_result_ids(server.server_id())
12139                        .into_iter()
12140                        .filter_map(|(abs_path, result_id)| {
12141                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12142                            Some(lsp::PreviousResultId {
12143                                uri,
12144                                value: result_id,
12145                            })
12146                        })
12147                        .collect()
12148                }) else {
12149                    return;
12150                };
12151
12152                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12153
12154                progress_rx.try_recv().ok();
12155                let timer =
12156                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12157                let progress = pin!(progress_rx.recv().fuse());
12158                let response_result = server
12159                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12160                        lsp::WorkspaceDiagnosticParams {
12161                            previous_result_ids,
12162                            identifier: identifier.clone(),
12163                            work_done_progress_params: Default::default(),
12164                            partial_result_params: lsp::PartialResultParams {
12165                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12166                            },
12167                        },
12168                        select(timer, progress).then(|either| match either {
12169                            Either::Left((message, ..)) => ready(message).left_future(),
12170                            Either::Right(..) => pending::<String>().right_future(),
12171                        }),
12172                    )
12173                    .await;
12174
12175                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12176                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12177                match response_result {
12178                    ConnectionResult::Timeout => {
12179                        log::error!("Timeout during workspace diagnostics pull");
12180                        continue 'request;
12181                    }
12182                    ConnectionResult::ConnectionReset => {
12183                        log::error!("Server closed a workspace diagnostics pull request");
12184                        continue 'request;
12185                    }
12186                    ConnectionResult::Result(Err(e)) => {
12187                        log::error!("Error during workspace diagnostics pull: {e:#}");
12188                        break 'request;
12189                    }
12190                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12191                        attempts = 0;
12192                        if lsp_store
12193                            .update(cx, |lsp_store, cx| {
12194                                lsp_store.apply_workspace_diagnostic_report(
12195                                    server.server_id(),
12196                                    pulled_diagnostics,
12197                                    cx,
12198                                )
12199                            })
12200                            .is_err()
12201                        {
12202                            return;
12203                        }
12204                        break 'request;
12205                    }
12206                }
12207            }
12208        }
12209    });
12210
12211    Some(WorkspaceRefreshTask {
12212        refresh_tx,
12213        progress_tx,
12214        task: workspace_query_language_server,
12215    })
12216}
12217
12218fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12219    let CompletionSource::BufferWord {
12220        word_range,
12221        resolved,
12222    } = &mut completion.source
12223    else {
12224        return;
12225    };
12226    if *resolved {
12227        return;
12228    }
12229
12230    if completion.new_text
12231        != snapshot
12232            .text_for_range(word_range.clone())
12233            .collect::<String>()
12234    {
12235        return;
12236    }
12237
12238    let mut offset = 0;
12239    for chunk in snapshot.chunks(word_range.clone(), true) {
12240        let end_offset = offset + chunk.text.len();
12241        if let Some(highlight_id) = chunk.syntax_highlight_id {
12242            completion
12243                .label
12244                .runs
12245                .push((offset..end_offset, highlight_id));
12246        }
12247        offset = end_offset;
12248    }
12249    *resolved = true;
12250}
12251
12252impl EventEmitter<LspStoreEvent> for LspStore {}
12253
12254fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12255    hover
12256        .contents
12257        .retain(|hover_block| !hover_block.text.trim().is_empty());
12258    if hover.contents.is_empty() {
12259        None
12260    } else {
12261        Some(hover)
12262    }
12263}
12264
12265async fn populate_labels_for_completions(
12266    new_completions: Vec<CoreCompletion>,
12267    language: Option<Arc<Language>>,
12268    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12269) -> Vec<Completion> {
12270    let lsp_completions = new_completions
12271        .iter()
12272        .filter_map(|new_completion| {
12273            new_completion
12274                .source
12275                .lsp_completion(true)
12276                .map(|lsp_completion| lsp_completion.into_owned())
12277        })
12278        .collect::<Vec<_>>();
12279
12280    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12281        lsp_adapter
12282            .labels_for_completions(&lsp_completions, language)
12283            .await
12284            .log_err()
12285            .unwrap_or_default()
12286    } else {
12287        Vec::new()
12288    }
12289    .into_iter()
12290    .fuse();
12291
12292    let mut completions = Vec::new();
12293    for completion in new_completions {
12294        match completion.source.lsp_completion(true) {
12295            Some(lsp_completion) => {
12296                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12297
12298                let mut label = labels.next().flatten().unwrap_or_else(|| {
12299                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12300                });
12301                ensure_uniform_list_compatible_label(&mut label);
12302                completions.push(Completion {
12303                    label,
12304                    documentation,
12305                    replace_range: completion.replace_range,
12306                    new_text: completion.new_text,
12307                    insert_text_mode: lsp_completion.insert_text_mode,
12308                    source: completion.source,
12309                    icon_path: None,
12310                    confirm: None,
12311                });
12312            }
12313            None => {
12314                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12315                ensure_uniform_list_compatible_label(&mut label);
12316                completions.push(Completion {
12317                    label,
12318                    documentation: None,
12319                    replace_range: completion.replace_range,
12320                    new_text: completion.new_text,
12321                    source: completion.source,
12322                    insert_text_mode: None,
12323                    icon_path: None,
12324                    confirm: None,
12325                });
12326            }
12327        }
12328    }
12329    completions
12330}
12331
12332#[derive(Debug)]
12333pub enum LanguageServerToQuery {
12334    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12335    FirstCapable,
12336    /// Query a specific language server.
12337    Other(LanguageServerId),
12338}
12339
12340#[derive(Default)]
12341struct RenamePathsWatchedForServer {
12342    did_rename: Vec<RenameActionPredicate>,
12343    will_rename: Vec<RenameActionPredicate>,
12344}
12345
12346impl RenamePathsWatchedForServer {
12347    fn with_did_rename_patterns(
12348        mut self,
12349        did_rename: Option<&FileOperationRegistrationOptions>,
12350    ) -> Self {
12351        if let Some(did_rename) = did_rename {
12352            self.did_rename = did_rename
12353                .filters
12354                .iter()
12355                .filter_map(|filter| filter.try_into().log_err())
12356                .collect();
12357        }
12358        self
12359    }
12360    fn with_will_rename_patterns(
12361        mut self,
12362        will_rename: Option<&FileOperationRegistrationOptions>,
12363    ) -> Self {
12364        if let Some(will_rename) = will_rename {
12365            self.will_rename = will_rename
12366                .filters
12367                .iter()
12368                .filter_map(|filter| filter.try_into().log_err())
12369                .collect();
12370        }
12371        self
12372    }
12373
12374    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12375        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12376    }
12377    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12378        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12379    }
12380}
12381
12382impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12383    type Error = globset::Error;
12384    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12385        Ok(Self {
12386            kind: ops.pattern.matches.clone(),
12387            glob: GlobBuilder::new(&ops.pattern.glob)
12388                .case_insensitive(
12389                    ops.pattern
12390                        .options
12391                        .as_ref()
12392                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12393                )
12394                .build()?
12395                .compile_matcher(),
12396        })
12397    }
12398}
12399struct RenameActionPredicate {
12400    glob: GlobMatcher,
12401    kind: Option<FileOperationPatternKind>,
12402}
12403
12404impl RenameActionPredicate {
12405    // Returns true if language server should be notified
12406    fn eval(&self, path: &str, is_dir: bool) -> bool {
12407        self.kind.as_ref().is_none_or(|kind| {
12408            let expected_kind = if is_dir {
12409                FileOperationPatternKind::Folder
12410            } else {
12411                FileOperationPatternKind::File
12412            };
12413            kind == &expected_kind
12414        }) && self.glob.is_match(path)
12415    }
12416}
12417
12418#[derive(Default)]
12419struct LanguageServerWatchedPaths {
12420    worktree_paths: HashMap<WorktreeId, GlobSet>,
12421    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12422}
12423
12424#[derive(Default)]
12425struct LanguageServerWatchedPathsBuilder {
12426    worktree_paths: HashMap<WorktreeId, GlobSet>,
12427    abs_paths: HashMap<Arc<Path>, GlobSet>,
12428}
12429
12430impl LanguageServerWatchedPathsBuilder {
12431    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12432        self.worktree_paths.insert(worktree_id, glob_set);
12433    }
12434    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12435        self.abs_paths.insert(path, glob_set);
12436    }
12437    fn build(
12438        self,
12439        fs: Arc<dyn Fs>,
12440        language_server_id: LanguageServerId,
12441        cx: &mut Context<LspStore>,
12442    ) -> LanguageServerWatchedPaths {
12443        let project = cx.weak_entity();
12444
12445        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12446        let abs_paths = self
12447            .abs_paths
12448            .into_iter()
12449            .map(|(abs_path, globset)| {
12450                let task = cx.spawn({
12451                    let abs_path = abs_path.clone();
12452                    let fs = fs.clone();
12453
12454                    let lsp_store = project.clone();
12455                    async move |_, cx| {
12456                        maybe!(async move {
12457                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12458                            while let Some(update) = push_updates.0.next().await {
12459                                let action = lsp_store
12460                                    .update(cx, |this, _| {
12461                                        let Some(local) = this.as_local() else {
12462                                            return ControlFlow::Break(());
12463                                        };
12464                                        let Some(watcher) = local
12465                                            .language_server_watched_paths
12466                                            .get(&language_server_id)
12467                                        else {
12468                                            return ControlFlow::Break(());
12469                                        };
12470                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12471                                            "Watched abs path is not registered with a watcher",
12472                                        );
12473                                        let matching_entries = update
12474                                            .into_iter()
12475                                            .filter(|event| globs.is_match(&event.path))
12476                                            .collect::<Vec<_>>();
12477                                        this.lsp_notify_abs_paths_changed(
12478                                            language_server_id,
12479                                            matching_entries,
12480                                        );
12481                                        ControlFlow::Continue(())
12482                                    })
12483                                    .ok()?;
12484
12485                                if action.is_break() {
12486                                    break;
12487                                }
12488                            }
12489                            Some(())
12490                        })
12491                        .await;
12492                    }
12493                });
12494                (abs_path, (globset, task))
12495            })
12496            .collect();
12497        LanguageServerWatchedPaths {
12498            worktree_paths: self.worktree_paths,
12499            abs_paths,
12500        }
12501    }
12502}
12503
12504struct LspBufferSnapshot {
12505    version: i32,
12506    snapshot: TextBufferSnapshot,
12507}
12508
12509/// A prompt requested by LSP server.
12510#[derive(Clone, Debug)]
12511pub struct LanguageServerPromptRequest {
12512    pub level: PromptLevel,
12513    pub message: String,
12514    pub actions: Vec<MessageActionItem>,
12515    pub lsp_name: String,
12516    pub(crate) response_channel: Sender<MessageActionItem>,
12517}
12518
12519impl LanguageServerPromptRequest {
12520    pub async fn respond(self, index: usize) -> Option<()> {
12521        if let Some(response) = self.actions.into_iter().nth(index) {
12522            self.response_channel.send(response).await.ok()
12523        } else {
12524            None
12525        }
12526    }
12527}
12528impl PartialEq for LanguageServerPromptRequest {
12529    fn eq(&self, other: &Self) -> bool {
12530        self.message == other.message && self.actions == other.actions
12531    }
12532}
12533
12534#[derive(Clone, Debug, PartialEq)]
12535pub enum LanguageServerLogType {
12536    Log(MessageType),
12537    Trace(Option<String>),
12538}
12539
12540impl LanguageServerLogType {
12541    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12542        match self {
12543            Self::Log(log_type) => {
12544                let message_type = match *log_type {
12545                    MessageType::ERROR => 1,
12546                    MessageType::WARNING => 2,
12547                    MessageType::INFO => 3,
12548                    MessageType::LOG => 4,
12549                    other => {
12550                        log::warn!("Unknown lsp log message type: {:?}", other);
12551                        4
12552                    }
12553                };
12554                proto::language_server_log::LogType::LogMessageType(message_type)
12555            }
12556            Self::Trace(message) => {
12557                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
12558                    message: message.clone(),
12559                })
12560            }
12561        }
12562    }
12563
12564    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12565        match log_type {
12566            proto::language_server_log::LogType::LogMessageType(message_type) => {
12567                Self::Log(match message_type {
12568                    1 => MessageType::ERROR,
12569                    2 => MessageType::WARNING,
12570                    3 => MessageType::INFO,
12571                    4 => MessageType::LOG,
12572                    _ => MessageType::LOG,
12573                })
12574            }
12575            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
12576        }
12577    }
12578}
12579
12580pub struct WorkspaceRefreshTask {
12581    refresh_tx: mpsc::Sender<()>,
12582    progress_tx: mpsc::Sender<()>,
12583    #[allow(dead_code)]
12584    task: Task<()>,
12585}
12586
12587pub enum LanguageServerState {
12588    Starting {
12589        startup: Task<Option<Arc<LanguageServer>>>,
12590        /// List of language servers that will be added to the workspace once it's initialization completes.
12591        pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
12592    },
12593
12594    Running {
12595        adapter: Arc<CachedLspAdapter>,
12596        server: Arc<LanguageServer>,
12597        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12598        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12599    },
12600}
12601
12602impl LanguageServerState {
12603    fn add_workspace_folder(&self, uri: Url) {
12604        match self {
12605            LanguageServerState::Starting {
12606                pending_workspace_folders,
12607                ..
12608            } => {
12609                pending_workspace_folders.lock().insert(uri);
12610            }
12611            LanguageServerState::Running { server, .. } => {
12612                server.add_workspace_folder(uri);
12613            }
12614        }
12615    }
12616    fn _remove_workspace_folder(&self, uri: Url) {
12617        match self {
12618            LanguageServerState::Starting {
12619                pending_workspace_folders,
12620                ..
12621            } => {
12622                pending_workspace_folders.lock().remove(&uri);
12623            }
12624            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12625        }
12626    }
12627}
12628
12629impl std::fmt::Debug for LanguageServerState {
12630    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12631        match self {
12632            LanguageServerState::Starting { .. } => {
12633                f.debug_struct("LanguageServerState::Starting").finish()
12634            }
12635            LanguageServerState::Running { .. } => {
12636                f.debug_struct("LanguageServerState::Running").finish()
12637            }
12638        }
12639    }
12640}
12641
12642#[derive(Clone, Debug, Serialize)]
12643pub struct LanguageServerProgress {
12644    pub is_disk_based_diagnostics_progress: bool,
12645    pub is_cancellable: bool,
12646    pub title: Option<String>,
12647    pub message: Option<String>,
12648    pub percentage: Option<usize>,
12649    #[serde(skip_serializing)]
12650    pub last_update_at: Instant,
12651}
12652
12653#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12654pub struct DiagnosticSummary {
12655    pub error_count: usize,
12656    pub warning_count: usize,
12657}
12658
12659impl DiagnosticSummary {
12660    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12661        let mut this = Self {
12662            error_count: 0,
12663            warning_count: 0,
12664        };
12665
12666        for entry in diagnostics {
12667            if entry.diagnostic.is_primary {
12668                match entry.diagnostic.severity {
12669                    DiagnosticSeverity::ERROR => this.error_count += 1,
12670                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12671                    _ => {}
12672                }
12673            }
12674        }
12675
12676        this
12677    }
12678
12679    pub fn is_empty(&self) -> bool {
12680        self.error_count == 0 && self.warning_count == 0
12681    }
12682
12683    pub fn to_proto(
12684        self,
12685        language_server_id: LanguageServerId,
12686        path: &Path,
12687    ) -> proto::DiagnosticSummary {
12688        proto::DiagnosticSummary {
12689            path: path.to_proto(),
12690            language_server_id: language_server_id.0 as u64,
12691            error_count: self.error_count as u32,
12692            warning_count: self.warning_count as u32,
12693        }
12694    }
12695}
12696
12697#[derive(Clone, Debug)]
12698pub enum CompletionDocumentation {
12699    /// There is no documentation for this completion.
12700    Undocumented,
12701    /// A single line of documentation.
12702    SingleLine(SharedString),
12703    /// Multiple lines of plain text documentation.
12704    MultiLinePlainText(SharedString),
12705    /// Markdown documentation.
12706    MultiLineMarkdown(SharedString),
12707    /// Both single line and multiple lines of plain text documentation.
12708    SingleLineAndMultiLinePlainText {
12709        single_line: SharedString,
12710        plain_text: Option<SharedString>,
12711    },
12712}
12713
12714impl From<lsp::Documentation> for CompletionDocumentation {
12715    fn from(docs: lsp::Documentation) -> Self {
12716        match docs {
12717            lsp::Documentation::String(text) => {
12718                if text.lines().count() <= 1 {
12719                    CompletionDocumentation::SingleLine(text.into())
12720                } else {
12721                    CompletionDocumentation::MultiLinePlainText(text.into())
12722                }
12723            }
12724
12725            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12726                lsp::MarkupKind::PlainText => {
12727                    if value.lines().count() <= 1 {
12728                        CompletionDocumentation::SingleLine(value.into())
12729                    } else {
12730                        CompletionDocumentation::MultiLinePlainText(value.into())
12731                    }
12732                }
12733
12734                lsp::MarkupKind::Markdown => {
12735                    CompletionDocumentation::MultiLineMarkdown(value.into())
12736                }
12737            },
12738        }
12739    }
12740}
12741
12742fn glob_literal_prefix(glob: &Path) -> PathBuf {
12743    glob.components()
12744        .take_while(|component| match component {
12745            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12746            _ => true,
12747        })
12748        .collect()
12749}
12750
12751pub struct SshLspAdapter {
12752    name: LanguageServerName,
12753    binary: LanguageServerBinary,
12754    initialization_options: Option<String>,
12755    code_action_kinds: Option<Vec<CodeActionKind>>,
12756}
12757
12758impl SshLspAdapter {
12759    pub fn new(
12760        name: LanguageServerName,
12761        binary: LanguageServerBinary,
12762        initialization_options: Option<String>,
12763        code_action_kinds: Option<String>,
12764    ) -> Self {
12765        Self {
12766            name,
12767            binary,
12768            initialization_options,
12769            code_action_kinds: code_action_kinds
12770                .as_ref()
12771                .and_then(|c| serde_json::from_str(c).ok()),
12772        }
12773    }
12774}
12775
12776#[async_trait(?Send)]
12777impl LspAdapter for SshLspAdapter {
12778    fn name(&self) -> LanguageServerName {
12779        self.name.clone()
12780    }
12781
12782    async fn initialization_options(
12783        self: Arc<Self>,
12784        _: &dyn Fs,
12785        _: &Arc<dyn LspAdapterDelegate>,
12786    ) -> Result<Option<serde_json::Value>> {
12787        let Some(options) = &self.initialization_options else {
12788            return Ok(None);
12789        };
12790        let result = serde_json::from_str(options)?;
12791        Ok(result)
12792    }
12793
12794    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12795        self.code_action_kinds.clone()
12796    }
12797
12798    async fn check_if_user_installed(
12799        &self,
12800        _: &dyn LspAdapterDelegate,
12801        _: Option<Toolchain>,
12802        _: &AsyncApp,
12803    ) -> Option<LanguageServerBinary> {
12804        Some(self.binary.clone())
12805    }
12806
12807    async fn cached_server_binary(
12808        &self,
12809        _: PathBuf,
12810        _: &dyn LspAdapterDelegate,
12811    ) -> Option<LanguageServerBinary> {
12812        None
12813    }
12814
12815    async fn fetch_latest_server_version(
12816        &self,
12817        _: &dyn LspAdapterDelegate,
12818    ) -> Result<Box<dyn 'static + Send + Any>> {
12819        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12820    }
12821
12822    async fn fetch_server_binary(
12823        &self,
12824        _: Box<dyn 'static + Send + Any>,
12825        _: PathBuf,
12826        _: &dyn LspAdapterDelegate,
12827    ) -> Result<LanguageServerBinary> {
12828        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12829    }
12830}
12831
12832pub fn language_server_settings<'a>(
12833    delegate: &'a dyn LspAdapterDelegate,
12834    language: &LanguageServerName,
12835    cx: &'a App,
12836) -> Option<&'a LspSettings> {
12837    language_server_settings_for(
12838        SettingsLocation {
12839            worktree_id: delegate.worktree_id(),
12840            path: delegate.worktree_root_path(),
12841        },
12842        language,
12843        cx,
12844    )
12845}
12846
12847pub(crate) fn language_server_settings_for<'a>(
12848    location: SettingsLocation<'a>,
12849    language: &LanguageServerName,
12850    cx: &'a App,
12851) -> Option<&'a LspSettings> {
12852    ProjectSettings::get(Some(location), cx).lsp.get(language)
12853}
12854
12855pub struct LocalLspAdapterDelegate {
12856    lsp_store: WeakEntity<LspStore>,
12857    worktree: worktree::Snapshot,
12858    fs: Arc<dyn Fs>,
12859    http_client: Arc<dyn HttpClient>,
12860    language_registry: Arc<LanguageRegistry>,
12861    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12862}
12863
12864impl LocalLspAdapterDelegate {
12865    pub fn new(
12866        language_registry: Arc<LanguageRegistry>,
12867        environment: &Entity<ProjectEnvironment>,
12868        lsp_store: WeakEntity<LspStore>,
12869        worktree: &Entity<Worktree>,
12870        http_client: Arc<dyn HttpClient>,
12871        fs: Arc<dyn Fs>,
12872        cx: &mut App,
12873    ) -> Arc<Self> {
12874        let load_shell_env_task = environment.update(cx, |env, cx| {
12875            env.get_worktree_environment(worktree.clone(), cx)
12876        });
12877
12878        Arc::new(Self {
12879            lsp_store,
12880            worktree: worktree.read(cx).snapshot(),
12881            fs,
12882            http_client,
12883            language_registry,
12884            load_shell_env_task,
12885        })
12886    }
12887
12888    fn from_local_lsp(
12889        local: &LocalLspStore,
12890        worktree: &Entity<Worktree>,
12891        cx: &mut App,
12892    ) -> Arc<Self> {
12893        Self::new(
12894            local.languages.clone(),
12895            &local.environment,
12896            local.weak.clone(),
12897            worktree,
12898            local.http_client.clone(),
12899            local.fs.clone(),
12900            cx,
12901        )
12902    }
12903}
12904
12905#[async_trait]
12906impl LspAdapterDelegate for LocalLspAdapterDelegate {
12907    fn show_notification(&self, message: &str, cx: &mut App) {
12908        self.lsp_store
12909            .update(cx, |_, cx| {
12910                cx.emit(LspStoreEvent::Notification(message.to_owned()))
12911            })
12912            .ok();
12913    }
12914
12915    fn http_client(&self) -> Arc<dyn HttpClient> {
12916        self.http_client.clone()
12917    }
12918
12919    fn worktree_id(&self) -> WorktreeId {
12920        self.worktree.id()
12921    }
12922
12923    fn worktree_root_path(&self) -> &Path {
12924        self.worktree.abs_path().as_ref()
12925    }
12926
12927    async fn shell_env(&self) -> HashMap<String, String> {
12928        let task = self.load_shell_env_task.clone();
12929        task.await.unwrap_or_default()
12930    }
12931
12932    async fn npm_package_installed_version(
12933        &self,
12934        package_name: &str,
12935    ) -> Result<Option<(PathBuf, String)>> {
12936        let local_package_directory = self.worktree_root_path();
12937        let node_modules_directory = local_package_directory.join("node_modules");
12938
12939        if let Some(version) =
12940            read_package_installed_version(node_modules_directory.clone(), package_name).await?
12941        {
12942            return Ok(Some((node_modules_directory, version)));
12943        }
12944        let Some(npm) = self.which("npm".as_ref()).await else {
12945            log::warn!(
12946                "Failed to find npm executable for {:?}",
12947                local_package_directory
12948            );
12949            return Ok(None);
12950        };
12951
12952        let env = self.shell_env().await;
12953        let output = util::command::new_smol_command(&npm)
12954            .args(["root", "-g"])
12955            .envs(env)
12956            .current_dir(local_package_directory)
12957            .output()
12958            .await?;
12959        let global_node_modules =
12960            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
12961
12962        if let Some(version) =
12963            read_package_installed_version(global_node_modules.clone(), package_name).await?
12964        {
12965            return Ok(Some((global_node_modules, version)));
12966        }
12967        return Ok(None);
12968    }
12969
12970    #[cfg(not(target_os = "windows"))]
12971    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12972        let worktree_abs_path = self.worktree.abs_path();
12973        let shell_path = self.shell_env().await.get("PATH").cloned();
12974        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
12975    }
12976
12977    #[cfg(target_os = "windows")]
12978    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12979        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
12980        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
12981        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
12982        which::which(command).ok()
12983    }
12984
12985    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
12986        let working_dir = self.worktree_root_path();
12987        let output = util::command::new_smol_command(&command.path)
12988            .args(command.arguments)
12989            .envs(command.env.clone().unwrap_or_default())
12990            .current_dir(working_dir)
12991            .output()
12992            .await?;
12993
12994        anyhow::ensure!(
12995            output.status.success(),
12996            "{}, stdout: {:?}, stderr: {:?}",
12997            output.status,
12998            String::from_utf8_lossy(&output.stdout),
12999            String::from_utf8_lossy(&output.stderr)
13000        );
13001        Ok(())
13002    }
13003
13004    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13005        self.language_registry
13006            .update_lsp_binary_status(server_name, status);
13007    }
13008
13009    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13010        self.language_registry
13011            .all_lsp_adapters()
13012            .into_iter()
13013            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13014            .collect()
13015    }
13016
13017    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13018        let dir = self.language_registry.language_server_download_dir(name)?;
13019
13020        if !dir.exists() {
13021            smol::fs::create_dir_all(&dir)
13022                .await
13023                .context("failed to create container directory")
13024                .log_err()?;
13025        }
13026
13027        Some(dir)
13028    }
13029
13030    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
13031        let entry = self
13032            .worktree
13033            .entry_for_path(&path)
13034            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13035        let abs_path = self
13036            .worktree
13037            .absolutize(&entry.path)
13038            .with_context(|| format!("cannot absolutize path {path:?}"))?;
13039
13040        self.fs.load(&abs_path).await
13041    }
13042}
13043
13044async fn populate_labels_for_symbols(
13045    symbols: Vec<CoreSymbol>,
13046    language_registry: &Arc<LanguageRegistry>,
13047    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13048    output: &mut Vec<Symbol>,
13049) {
13050    #[allow(clippy::mutable_key_type)]
13051    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13052
13053    let mut unknown_paths = BTreeSet::new();
13054    for symbol in symbols {
13055        let language = language_registry
13056            .language_for_file_path(&symbol.path.path)
13057            .await
13058            .ok()
13059            .or_else(|| {
13060                unknown_paths.insert(symbol.path.path.clone());
13061                None
13062            });
13063        symbols_by_language
13064            .entry(language)
13065            .or_default()
13066            .push(symbol);
13067    }
13068
13069    for unknown_path in unknown_paths {
13070        log::info!(
13071            "no language found for symbol path {}",
13072            unknown_path.display()
13073        );
13074    }
13075
13076    let mut label_params = Vec::new();
13077    for (language, mut symbols) in symbols_by_language {
13078        label_params.clear();
13079        label_params.extend(
13080            symbols
13081                .iter_mut()
13082                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13083        );
13084
13085        let mut labels = Vec::new();
13086        if let Some(language) = language {
13087            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13088                language_registry
13089                    .lsp_adapters(&language.name())
13090                    .first()
13091                    .cloned()
13092            });
13093            if let Some(lsp_adapter) = lsp_adapter {
13094                labels = lsp_adapter
13095                    .labels_for_symbols(&label_params, &language)
13096                    .await
13097                    .log_err()
13098                    .unwrap_or_default();
13099            }
13100        }
13101
13102        for ((symbol, (name, _)), label) in symbols
13103            .into_iter()
13104            .zip(label_params.drain(..))
13105            .zip(labels.into_iter().chain(iter::repeat(None)))
13106        {
13107            output.push(Symbol {
13108                language_server_name: symbol.language_server_name,
13109                source_worktree_id: symbol.source_worktree_id,
13110                source_language_server_id: symbol.source_language_server_id,
13111                path: symbol.path,
13112                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13113                name,
13114                kind: symbol.kind,
13115                range: symbol.range,
13116                signature: symbol.signature,
13117            });
13118        }
13119    }
13120}
13121
13122fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13123    match server.capabilities().text_document_sync.as_ref()? {
13124        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13125            // Server wants didSave but didn't specify includeText.
13126            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13127            // Server doesn't want didSave at all.
13128            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13129            // Server provided SaveOptions.
13130            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13131                Some(save_options.include_text.unwrap_or(false))
13132            }
13133        },
13134        // We do not have any save info. Kind affects didChange only.
13135        lsp::TextDocumentSyncCapability::Kind(_) => None,
13136    }
13137}
13138
13139/// Completion items are displayed in a `UniformList`.
13140/// Usually, those items are single-line strings, but in LSP responses,
13141/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13142/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13143/// 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,
13144/// breaking the completions menu presentation.
13145///
13146/// 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.
13147fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13148    let mut new_text = String::with_capacity(label.text.len());
13149    let mut offset_map = vec![0; label.text.len() + 1];
13150    let mut last_char_was_space = false;
13151    let mut new_idx = 0;
13152    let mut chars = label.text.char_indices().fuse();
13153    let mut newlines_removed = false;
13154
13155    while let Some((idx, c)) = chars.next() {
13156        offset_map[idx] = new_idx;
13157
13158        match c {
13159            '\n' if last_char_was_space => {
13160                newlines_removed = true;
13161            }
13162            '\t' | ' ' if last_char_was_space => {}
13163            '\n' if !last_char_was_space => {
13164                new_text.push(' ');
13165                new_idx += 1;
13166                last_char_was_space = true;
13167                newlines_removed = true;
13168            }
13169            ' ' | '\t' => {
13170                new_text.push(' ');
13171                new_idx += 1;
13172                last_char_was_space = true;
13173            }
13174            _ => {
13175                new_text.push(c);
13176                new_idx += c.len_utf8();
13177                last_char_was_space = false;
13178            }
13179        }
13180    }
13181    offset_map[label.text.len()] = new_idx;
13182
13183    // Only modify the label if newlines were removed.
13184    if !newlines_removed {
13185        return;
13186    }
13187
13188    let last_index = new_idx;
13189    let mut run_ranges_errors = Vec::new();
13190    label.runs.retain_mut(|(range, _)| {
13191        match offset_map.get(range.start) {
13192            Some(&start) => range.start = start,
13193            None => {
13194                run_ranges_errors.push(range.clone());
13195                return false;
13196            }
13197        }
13198
13199        match offset_map.get(range.end) {
13200            Some(&end) => range.end = end,
13201            None => {
13202                run_ranges_errors.push(range.clone());
13203                range.end = last_index;
13204            }
13205        }
13206        true
13207    });
13208    if !run_ranges_errors.is_empty() {
13209        log::error!(
13210            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13211            label.text
13212        );
13213    }
13214
13215    let mut wrong_filter_range = None;
13216    if label.filter_range == (0..label.text.len()) {
13217        label.filter_range = 0..new_text.len();
13218    } else {
13219        let mut original_filter_range = Some(label.filter_range.clone());
13220        match offset_map.get(label.filter_range.start) {
13221            Some(&start) => label.filter_range.start = start,
13222            None => {
13223                wrong_filter_range = original_filter_range.take();
13224                label.filter_range.start = last_index;
13225            }
13226        }
13227
13228        match offset_map.get(label.filter_range.end) {
13229            Some(&end) => label.filter_range.end = end,
13230            None => {
13231                wrong_filter_range = original_filter_range.take();
13232                label.filter_range.end = last_index;
13233            }
13234        }
13235    }
13236    if let Some(wrong_filter_range) = wrong_filter_range {
13237        log::error!(
13238            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13239            label.text
13240        );
13241    }
13242
13243    label.text = new_text;
13244}
13245
13246#[cfg(test)]
13247mod tests {
13248    use language::HighlightId;
13249
13250    use super::*;
13251
13252    #[test]
13253    fn test_glob_literal_prefix() {
13254        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13255        assert_eq!(
13256            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13257            Path::new("node_modules")
13258        );
13259        assert_eq!(
13260            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13261            Path::new("foo")
13262        );
13263        assert_eq!(
13264            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13265            Path::new("foo/bar/baz.js")
13266        );
13267
13268        #[cfg(target_os = "windows")]
13269        {
13270            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13271            assert_eq!(
13272                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13273                Path::new("node_modules")
13274            );
13275            assert_eq!(
13276                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13277                Path::new("foo")
13278            );
13279            assert_eq!(
13280                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13281                Path::new("foo/bar/baz.js")
13282            );
13283        }
13284    }
13285
13286    #[test]
13287    fn test_multi_len_chars_normalization() {
13288        let mut label = CodeLabel {
13289            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13290            runs: vec![(0..6, HighlightId(1))],
13291            filter_range: 0..6,
13292        };
13293        ensure_uniform_list_compatible_label(&mut label);
13294        assert_eq!(
13295            label,
13296            CodeLabel {
13297                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13298                runs: vec![(0..6, HighlightId(1))],
13299                filter_range: 0..6,
13300            }
13301        );
13302    }
13303}