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