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