lsp_store.rs

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