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, TextEdit, WillRenameFiles, WorkDoneProgressCancelParams,
   78    WorkspaceFolder, notification::DidRenameFiles,
   79};
   80use node_runtime::read_package_installed_version;
   81use parking_lot::Mutex;
   82use postage::{mpsc, sink::Sink, stream::Stream, watch};
   83use rand::prelude::*;
   84
   85use rpc::{
   86    AnyProtoClient,
   87    proto::{FromProto, ToProto},
   88};
   89use serde::Serialize;
   90use settings::{Settings, SettingsLocation, SettingsStore};
   91use sha2::{Digest, Sha256};
   92use smol::channel::Sender;
   93use snippet::Snippet;
   94use std::{
   95    any::Any,
   96    borrow::Cow,
   97    cell::RefCell,
   98    cmp::{Ordering, Reverse},
   99    convert::TryInto,
  100    ffi::OsStr,
  101    future::ready,
  102    iter, mem,
  103    ops::{ControlFlow, Range},
  104    path::{self, Path, PathBuf},
  105    pin::pin,
  106    rc::Rc,
  107    sync::Arc,
  108    time::{Duration, Instant},
  109};
  110use sum_tree::Dimensions;
  111use text::{Anchor, BufferId, LineEnding, OffsetRangeExt};
  112use url::Url;
  113use util::{
  114    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  115    paths::{PathExt, SanitizedPath},
  116    post_inc,
  117};
  118
  119pub use fs::*;
  120pub use language::Location;
  121#[cfg(any(test, feature = "test-support"))]
  122pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  123pub use worktree::{
  124    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  125    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  126};
  127
  128const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  129pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  130
  131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  132pub enum FormatTrigger {
  133    Save,
  134    Manual,
  135}
  136
  137pub enum LspFormatTarget {
  138    Buffers,
  139    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  140}
  141
  142pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  143
  144impl FormatTrigger {
  145    fn from_proto(value: i32) -> FormatTrigger {
  146        match value {
  147            0 => FormatTrigger::Save,
  148            1 => FormatTrigger::Manual,
  149            _ => FormatTrigger::Save,
  150        }
  151    }
  152}
  153
  154#[derive(Clone)]
  155struct UnifiedLanguageServer {
  156    id: LanguageServerId,
  157    project_roots: HashSet<Arc<Path>>,
  158}
  159
  160#[derive(Clone, Hash, PartialEq, Eq)]
  161struct LanguageServerSeed {
  162    worktree_id: WorktreeId,
  163    name: LanguageServerName,
  164    toolchain: Option<Toolchain>,
  165    settings: Arc<LspSettings>,
  166}
  167
  168#[derive(Debug)]
  169pub struct DocumentDiagnosticsUpdate<'a, D> {
  170    pub diagnostics: D,
  171    pub result_id: Option<String>,
  172    pub server_id: LanguageServerId,
  173    pub disk_based_sources: Cow<'a, [String]>,
  174}
  175
  176pub struct DocumentDiagnostics {
  177    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  178    document_abs_path: PathBuf,
  179    version: Option<i32>,
  180}
  181
  182pub struct LocalLspStore {
  183    weak: WeakEntity<LspStore>,
  184    worktree_store: Entity<WorktreeStore>,
  185    toolchain_store: Entity<LocalToolchainStore>,
  186    http_client: Arc<dyn HttpClient>,
  187    environment: Entity<ProjectEnvironment>,
  188    fs: Arc<dyn Fs>,
  189    languages: Arc<LanguageRegistry>,
  190    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  191    yarn: Entity<YarnPathStore>,
  192    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  193    buffers_being_formatted: HashSet<BufferId>,
  194    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  195    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  196    watched_manifest_filenames: HashSet<ManifestName>,
  197    language_server_paths_watched_for_rename:
  198        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  199    language_server_watcher_registrations:
  200        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
  201    supplementary_language_servers:
  202        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  203    prettier_store: Entity<PrettierStore>,
  204    next_diagnostic_group_id: usize,
  205    diagnostics: HashMap<
  206        WorktreeId,
  207        HashMap<
  208            Arc<Path>,
  209            Vec<(
  210                LanguageServerId,
  211                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  212            )>,
  213        >,
  214    >,
  215    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  216    _subscription: gpui::Subscription,
  217    lsp_tree: LanguageServerTree,
  218    registered_buffers: HashMap<BufferId, usize>,
  219    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  220    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  221}
  222
  223impl LocalLspStore {
  224    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  225    pub fn running_language_server_for_id(
  226        &self,
  227        id: LanguageServerId,
  228    ) -> Option<&Arc<LanguageServer>> {
  229        let language_server_state = self.language_servers.get(&id)?;
  230
  231        match language_server_state {
  232            LanguageServerState::Running { server, .. } => Some(server),
  233            LanguageServerState::Starting { .. } => None,
  234        }
  235    }
  236
  237    fn get_or_insert_language_server(
  238        &mut self,
  239        worktree_handle: &Entity<Worktree>,
  240        delegate: Arc<LocalLspAdapterDelegate>,
  241        disposition: &Arc<LaunchDisposition>,
  242        language_name: &LanguageName,
  243        cx: &mut App,
  244    ) -> LanguageServerId {
  245        let key = LanguageServerSeed {
  246            worktree_id: worktree_handle.read(cx).id(),
  247            name: disposition.server_name.clone(),
  248            settings: disposition.settings.clone(),
  249            toolchain: disposition.toolchain.clone(),
  250        };
  251        if let Some(state) = self.language_server_ids.get_mut(&key) {
  252            state.project_roots.insert(disposition.path.path.clone());
  253            state.id
  254        } else {
  255            let adapter = self
  256                .languages
  257                .lsp_adapters(language_name)
  258                .into_iter()
  259                .find(|adapter| adapter.name() == disposition.server_name)
  260                .expect("To find LSP adapter");
  261            let new_language_server_id = self.start_language_server(
  262                worktree_handle,
  263                delegate,
  264                adapter,
  265                disposition.settings.clone(),
  266                key.clone(),
  267                cx,
  268            );
  269            if let Some(state) = self.language_server_ids.get_mut(&key) {
  270                state.project_roots.insert(disposition.path.path.clone());
  271            } else {
  272                debug_assert!(
  273                    false,
  274                    "Expected `start_language_server` to ensure that `key` exists in a map"
  275                );
  276            }
  277            new_language_server_id
  278        }
  279    }
  280
  281    fn start_language_server(
  282        &mut self,
  283        worktree_handle: &Entity<Worktree>,
  284        delegate: Arc<LocalLspAdapterDelegate>,
  285        adapter: Arc<CachedLspAdapter>,
  286        settings: Arc<LspSettings>,
  287        key: LanguageServerSeed,
  288        cx: &mut App,
  289    ) -> LanguageServerId {
  290        let worktree = worktree_handle.read(cx);
  291
  292        let root_path = worktree.abs_path();
  293        let toolchain = key.toolchain.clone();
  294        let override_options = settings.initialization_options.clone();
  295
  296        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  297
  298        let server_id = self.languages.next_language_server_id();
  299        log::info!(
  300            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  301            adapter.name.0
  302        );
  303
  304        let binary = self.get_language_server_binary(
  305            adapter.clone(),
  306            settings,
  307            toolchain.clone(),
  308            delegate.clone(),
  309            true,
  310            cx,
  311        );
  312        let pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
  313
  314        let pending_server = cx.spawn({
  315            let adapter = adapter.clone();
  316            let server_name = adapter.name.clone();
  317            let stderr_capture = stderr_capture.clone();
  318            #[cfg(any(test, feature = "test-support"))]
  319            let lsp_store = self.weak.clone();
  320            let pending_workspace_folders = pending_workspace_folders.clone();
  321            async move |cx| {
  322                let binary = binary.await?;
  323                #[cfg(any(test, feature = "test-support"))]
  324                if let Some(server) = lsp_store
  325                    .update(&mut cx.clone(), |this, cx| {
  326                        this.languages.create_fake_language_server(
  327                            server_id,
  328                            &server_name,
  329                            binary.clone(),
  330                            &mut cx.to_async(),
  331                        )
  332                    })
  333                    .ok()
  334                    .flatten()
  335                {
  336                    return Ok(server);
  337                }
  338
  339                let code_action_kinds = adapter.code_action_kinds();
  340                lsp::LanguageServer::new(
  341                    stderr_capture,
  342                    server_id,
  343                    server_name,
  344                    binary,
  345                    &root_path,
  346                    code_action_kinds,
  347                    Some(pending_workspace_folders),
  348                    cx,
  349                )
  350            }
  351        });
  352
  353        let startup = {
  354            let server_name = adapter.name.0.clone();
  355            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  356            let key = key.clone();
  357            let adapter = adapter.clone();
  358            let lsp_store = self.weak.clone();
  359            let pending_workspace_folders = pending_workspace_folders.clone();
  360            let fs = self.fs.clone();
  361            let pull_diagnostics = ProjectSettings::get_global(cx)
  362                .diagnostics
  363                .lsp_pull_diagnostics
  364                .enabled;
  365            cx.spawn(async move |cx| {
  366                let result = async {
  367                    let language_server = pending_server.await?;
  368
  369                    let workspace_config = Self::workspace_configuration_for_adapter(
  370                        adapter.adapter.clone(),
  371                        fs.as_ref(),
  372                        &delegate,
  373                        toolchain,
  374                        cx,
  375                    )
  376                    .await?;
  377
  378                    let mut initialization_options = Self::initialization_options_for_adapter(
  379                        adapter.adapter.clone(),
  380                        fs.as_ref(),
  381                        &delegate,
  382                    )
  383                    .await?;
  384
  385                    match (&mut initialization_options, override_options) {
  386                        (Some(initialization_options), Some(override_options)) => {
  387                            merge_json_value_into(override_options, initialization_options);
  388                        }
  389                        (None, override_options) => initialization_options = override_options,
  390                        _ => {}
  391                    }
  392
  393                    let initialization_params = cx.update(|cx| {
  394                        let mut params =
  395                            language_server.default_initialize_params(pull_diagnostics, cx);
  396                        params.initialization_options = initialization_options;
  397                        adapter.adapter.prepare_initialize_params(params, cx)
  398                    })??;
  399
  400                    Self::setup_lsp_messages(
  401                        lsp_store.clone(),
  402                        fs,
  403                        &language_server,
  404                        delegate.clone(),
  405                        adapter.clone(),
  406                    );
  407
  408                    let did_change_configuration_params =
  409                        Arc::new(lsp::DidChangeConfigurationParams {
  410                            settings: workspace_config,
  411                        });
  412                    let language_server = cx
  413                        .update(|cx| {
  414                            language_server.initialize(
  415                                initialization_params,
  416                                did_change_configuration_params.clone(),
  417                                cx,
  418                            )
  419                        })?
  420                        .await
  421                        .inspect_err(|_| {
  422                            if let Some(lsp_store) = lsp_store.upgrade() {
  423                                lsp_store
  424                                    .update(cx, |lsp_store, cx| {
  425                                        lsp_store.cleanup_lsp_data(server_id);
  426                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  427                                    })
  428                                    .ok();
  429                            }
  430                        })?;
  431
  432                    language_server
  433                        .notify::<lsp::notification::DidChangeConfiguration>(
  434                            &did_change_configuration_params,
  435                        )
  436                        .ok();
  437
  438                    anyhow::Ok(language_server)
  439                }
  440                .await;
  441
  442                match result {
  443                    Ok(server) => {
  444                        lsp_store
  445                            .update(cx, |lsp_store, cx| {
  446                                lsp_store.insert_newly_running_language_server(
  447                                    adapter,
  448                                    server.clone(),
  449                                    server_id,
  450                                    key,
  451                                    pending_workspace_folders,
  452                                    cx,
  453                                );
  454                            })
  455                            .ok();
  456                        stderr_capture.lock().take();
  457                        Some(server)
  458                    }
  459
  460                    Err(err) => {
  461                        let log = stderr_capture.lock().take().unwrap_or_default();
  462                        delegate.update_status(
  463                            adapter.name(),
  464                            BinaryStatus::Failed {
  465                                error: if log.is_empty() {
  466                                    format!("{err:#}")
  467                                } else {
  468                                    format!("{err:#}\n-- stderr --\n{log}")
  469                                },
  470                            },
  471                        );
  472                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  473                        if !log.is_empty() {
  474                            log::error!("server stderr: {log}");
  475                        }
  476                        None
  477                    }
  478                }
  479            })
  480        };
  481        let state = LanguageServerState::Starting {
  482            startup,
  483            pending_workspace_folders,
  484        };
  485
  486        self.languages
  487            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  488
  489        self.language_servers.insert(server_id, state);
  490        self.language_server_ids
  491            .entry(key)
  492            .or_insert(UnifiedLanguageServer {
  493                id: server_id,
  494                project_roots: Default::default(),
  495            });
  496        server_id
  497    }
  498
  499    fn get_language_server_binary(
  500        &self,
  501        adapter: Arc<CachedLspAdapter>,
  502        settings: Arc<LspSettings>,
  503        toolchain: Option<Toolchain>,
  504        delegate: Arc<dyn LspAdapterDelegate>,
  505        allow_binary_download: bool,
  506        cx: &mut App,
  507    ) -> Task<Result<LanguageServerBinary>> {
  508        if let Some(settings) = settings.binary.as_ref()
  509            && settings.path.is_some()
  510        {
  511            let settings = settings.clone();
  512
  513            return cx.background_spawn(async move {
  514                let mut env = delegate.shell_env().await;
  515                env.extend(settings.env.unwrap_or_default());
  516
  517                Ok(LanguageServerBinary {
  518                    path: PathBuf::from(&settings.path.unwrap()),
  519                    env: Some(env),
  520                    arguments: settings
  521                        .arguments
  522                        .unwrap_or_default()
  523                        .iter()
  524                        .map(Into::into)
  525                        .collect(),
  526                })
  527            });
  528        }
  529        let lsp_binary_options = LanguageServerBinaryOptions {
  530            allow_path_lookup: !settings
  531                .binary
  532                .as_ref()
  533                .and_then(|b| b.ignore_system_version)
  534                .unwrap_or_default(),
  535            allow_binary_download,
  536        };
  537
  538        cx.spawn(async move |cx| {
  539            let binary_result = adapter
  540                .clone()
  541                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  542                .await;
  543
  544            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  545
  546            let mut binary = binary_result?;
  547            let mut shell_env = delegate.shell_env().await;
  548
  549            shell_env.extend(binary.env.unwrap_or_default());
  550
  551            if let Some(settings) = settings.binary.as_ref() {
  552                if let Some(arguments) = &settings.arguments {
  553                    binary.arguments = arguments.into_iter().map(Into::into).collect();
  554                }
  555                if let Some(env) = &settings.env {
  556                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  557                }
  558            }
  559
  560            binary.env = Some(shell_env);
  561            Ok(binary)
  562        })
  563    }
  564
  565    fn setup_lsp_messages(
  566        this: WeakEntity<LspStore>,
  567        fs: Arc<dyn Fs>,
  568        language_server: &LanguageServer,
  569        delegate: Arc<dyn LspAdapterDelegate>,
  570        adapter: Arc<CachedLspAdapter>,
  571    ) {
  572        let name = language_server.name();
  573        let server_id = language_server.server_id();
  574        language_server
  575            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  576                let adapter = adapter.clone();
  577                let this = this.clone();
  578                move |mut params, cx| {
  579                    let adapter = adapter.clone();
  580                    if let Some(this) = this.upgrade() {
  581                        this.update(cx, |this, cx| {
  582                            {
  583                                let buffer = params
  584                                    .uri
  585                                    .to_file_path()
  586                                    .map(|file_path| this.get_buffer(&file_path, cx))
  587                                    .ok()
  588                                    .flatten();
  589                                adapter.process_diagnostics(&mut params, server_id, buffer);
  590                            }
  591
  592                            this.merge_lsp_diagnostics(
  593                                DiagnosticSourceKind::Pushed,
  594                                vec![DocumentDiagnosticsUpdate {
  595                                    server_id,
  596                                    diagnostics: params,
  597                                    result_id: None,
  598                                    disk_based_sources: Cow::Borrowed(
  599                                        &adapter.disk_based_diagnostic_sources,
  600                                    ),
  601                                }],
  602                                |_, diagnostic, cx| match diagnostic.source_kind {
  603                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  604                                        adapter.retain_old_diagnostic(diagnostic, cx)
  605                                    }
  606                                    DiagnosticSourceKind::Pulled => true,
  607                                },
  608                                cx,
  609                            )
  610                            .log_err();
  611                        })
  612                        .ok();
  613                    }
  614                }
  615            })
  616            .detach();
  617        language_server
  618            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  619                let adapter = adapter.adapter.clone();
  620                let delegate = delegate.clone();
  621                let this = this.clone();
  622                let fs = fs.clone();
  623                move |params, cx| {
  624                    let adapter = adapter.clone();
  625                    let delegate = delegate.clone();
  626                    let this = this.clone();
  627                    let fs = fs.clone();
  628                    let mut cx = cx.clone();
  629                    async move {
  630                        let toolchain_for_id = this
  631                            .update(&mut cx, |this, _| {
  632                                this.as_local()?.language_server_ids.iter().find_map(
  633                                    |(seed, value)| {
  634                                        (value.id == server_id).then(|| seed.toolchain.clone())
  635                                    },
  636                                )
  637                            })?
  638                            .context("Expected the LSP store to be in a local mode")?;
  639                        let workspace_config = Self::workspace_configuration_for_adapter(
  640                            adapter.clone(),
  641                            fs.as_ref(),
  642                            &delegate,
  643                            toolchain_for_id,
  644                            &mut cx,
  645                        )
  646                        .await?;
  647
  648                        Ok(params
  649                            .items
  650                            .into_iter()
  651                            .map(|item| {
  652                                if let Some(section) = &item.section {
  653                                    workspace_config
  654                                        .get(section)
  655                                        .cloned()
  656                                        .unwrap_or(serde_json::Value::Null)
  657                                } else {
  658                                    workspace_config.clone()
  659                                }
  660                            })
  661                            .collect())
  662                    }
  663                }
  664            })
  665            .detach();
  666
  667        language_server
  668            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  669                let this = this.clone();
  670                move |_, cx| {
  671                    let this = this.clone();
  672                    let mut cx = cx.clone();
  673                    async move {
  674                        let Some(server) = this
  675                            .read_with(&mut cx, |this, _| this.language_server_for_id(server_id))?
  676                        else {
  677                            return Ok(None);
  678                        };
  679                        let root = server.workspace_folders();
  680                        Ok(Some(
  681                            root.into_iter()
  682                                .map(|uri| WorkspaceFolder {
  683                                    uri,
  684                                    name: Default::default(),
  685                                })
  686                                .collect(),
  687                        ))
  688                    }
  689                }
  690            })
  691            .detach();
  692        // Even though we don't have handling for these requests, respond to them to
  693        // avoid stalling any language server like `gopls` which waits for a response
  694        // to these requests when initializing.
  695        language_server
  696            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  697                let this = this.clone();
  698                move |params, cx| {
  699                    let this = this.clone();
  700                    let mut cx = cx.clone();
  701                    async move {
  702                        this.update(&mut cx, |this, _| {
  703                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  704                                && let lsp::NumberOrString::String(token) = params.token {
  705                                    status.progress_tokens.insert(token);
  706                                }
  707                        })?;
  708
  709                        Ok(())
  710                    }
  711                }
  712            })
  713            .detach();
  714
  715        language_server
  716            .on_request::<lsp::request::RegisterCapability, _, _>({
  717                let lsp_store = this.clone();
  718                move |params, cx| {
  719                    let lsp_store = lsp_store.clone();
  720                    let mut cx = cx.clone();
  721                    async move {
  722                        lsp_store
  723                            .update(&mut cx, |lsp_store, cx| {
  724                                if lsp_store.as_local().is_some() {
  725                                    match lsp_store
  726                                        .register_server_capabilities(server_id, params, cx)
  727                                    {
  728                                        Ok(()) => {}
  729                                        Err(e) => {
  730                                            log::error!(
  731                                                "Failed to register server capabilities: {e:#}"
  732                                            );
  733                                        }
  734                                    };
  735                                }
  736                            })
  737                            .ok();
  738                        Ok(())
  739                    }
  740                }
  741            })
  742            .detach();
  743
  744        language_server
  745            .on_request::<lsp::request::UnregisterCapability, _, _>({
  746                let lsp_store = this.clone();
  747                move |params, cx| {
  748                    let lsp_store = lsp_store.clone();
  749                    let mut cx = cx.clone();
  750                    async move {
  751                        lsp_store
  752                            .update(&mut cx, |lsp_store, cx| {
  753                                if lsp_store.as_local().is_some() {
  754                                    match lsp_store
  755                                        .unregister_server_capabilities(server_id, params, cx)
  756                                    {
  757                                        Ok(()) => {}
  758                                        Err(e) => {
  759                                            log::error!(
  760                                                "Failed to unregister server capabilities: {e:#}"
  761                                            );
  762                                        }
  763                                    }
  764                                }
  765                            })
  766                            .ok();
  767                        Ok(())
  768                    }
  769                }
  770            })
  771            .detach();
  772
  773        language_server
  774            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  775                let this = this.clone();
  776                move |params, cx| {
  777                    let mut cx = cx.clone();
  778                    let this = this.clone();
  779                    async move {
  780                        LocalLspStore::on_lsp_workspace_edit(
  781                            this.clone(),
  782                            params,
  783                            server_id,
  784                            &mut cx,
  785                        )
  786                        .await
  787                    }
  788                }
  789            })
  790            .detach();
  791
  792        language_server
  793            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  794                let this = this.clone();
  795                move |(), cx| {
  796                    let this = this.clone();
  797                    let mut cx = cx.clone();
  798                    async move {
  799                        this.update(&mut cx, |this, cx| {
  800                            cx.emit(LspStoreEvent::RefreshInlayHints);
  801                            this.downstream_client.as_ref().map(|(client, project_id)| {
  802                                client.send(proto::RefreshInlayHints {
  803                                    project_id: *project_id,
  804                                })
  805                            })
  806                        })?
  807                        .transpose()?;
  808                        Ok(())
  809                    }
  810                }
  811            })
  812            .detach();
  813
  814        language_server
  815            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  816                let this = this.clone();
  817                move |(), cx| {
  818                    let this = this.clone();
  819                    let mut cx = cx.clone();
  820                    async move {
  821                        this.update(&mut cx, |this, cx| {
  822                            cx.emit(LspStoreEvent::RefreshCodeLens);
  823                            this.downstream_client.as_ref().map(|(client, project_id)| {
  824                                client.send(proto::RefreshCodeLens {
  825                                    project_id: *project_id,
  826                                })
  827                            })
  828                        })?
  829                        .transpose()?;
  830                        Ok(())
  831                    }
  832                }
  833            })
  834            .detach();
  835
  836        language_server
  837            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  838                let this = this.clone();
  839                move |(), cx| {
  840                    let this = this.clone();
  841                    let mut cx = cx.clone();
  842                    async move {
  843                        this.update(&mut cx, |lsp_store, _| {
  844                            lsp_store.pull_workspace_diagnostics(server_id);
  845                            lsp_store
  846                                .downstream_client
  847                                .as_ref()
  848                                .map(|(client, project_id)| {
  849                                    client.send(proto::PullWorkspaceDiagnostics {
  850                                        project_id: *project_id,
  851                                        server_id: server_id.to_proto(),
  852                                    })
  853                                })
  854                        })?
  855                        .transpose()?;
  856                        Ok(())
  857                    }
  858                }
  859            })
  860            .detach();
  861
  862        language_server
  863            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  864                let this = this.clone();
  865                let name = name.to_string();
  866                move |params, cx| {
  867                    let this = this.clone();
  868                    let name = name.to_string();
  869                    let mut cx = cx.clone();
  870                    async move {
  871                        let actions = params.actions.unwrap_or_default();
  872                        let (tx, rx) = smol::channel::bounded(1);
  873                        let request = LanguageServerPromptRequest {
  874                            level: match params.typ {
  875                                lsp::MessageType::ERROR => PromptLevel::Critical,
  876                                lsp::MessageType::WARNING => PromptLevel::Warning,
  877                                _ => PromptLevel::Info,
  878                            },
  879                            message: params.message,
  880                            actions,
  881                            response_channel: tx,
  882                            lsp_name: name.clone(),
  883                        };
  884
  885                        let did_update = this
  886                            .update(&mut cx, |_, cx| {
  887                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  888                            })
  889                            .is_ok();
  890                        if did_update {
  891                            let response = rx.recv().await.ok();
  892                            Ok(response)
  893                        } else {
  894                            Ok(None)
  895                        }
  896                    }
  897                }
  898            })
  899            .detach();
  900        language_server
  901            .on_notification::<lsp::notification::ShowMessage, _>({
  902                let this = this.clone();
  903                let name = name.to_string();
  904                move |params, cx| {
  905                    let this = this.clone();
  906                    let name = name.to_string();
  907                    let mut cx = cx.clone();
  908
  909                    let (tx, _) = smol::channel::bounded(1);
  910                    let request = LanguageServerPromptRequest {
  911                        level: match params.typ {
  912                            lsp::MessageType::ERROR => PromptLevel::Critical,
  913                            lsp::MessageType::WARNING => PromptLevel::Warning,
  914                            _ => PromptLevel::Info,
  915                        },
  916                        message: params.message,
  917                        actions: vec![],
  918                        response_channel: tx,
  919                        lsp_name: name.clone(),
  920                    };
  921
  922                    let _ = this.update(&mut cx, |_, cx| {
  923                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  924                    });
  925                }
  926            })
  927            .detach();
  928
  929        let disk_based_diagnostics_progress_token =
  930            adapter.disk_based_diagnostics_progress_token.clone();
  931
  932        language_server
  933            .on_notification::<lsp::notification::Progress, _>({
  934                let this = this.clone();
  935                move |params, cx| {
  936                    if let Some(this) = this.upgrade() {
  937                        this.update(cx, |this, cx| {
  938                            this.on_lsp_progress(
  939                                params,
  940                                server_id,
  941                                disk_based_diagnostics_progress_token.clone(),
  942                                cx,
  943                            );
  944                        })
  945                        .ok();
  946                    }
  947                }
  948            })
  949            .detach();
  950
  951        language_server
  952            .on_notification::<lsp::notification::LogMessage, _>({
  953                let this = this.clone();
  954                move |params, cx| {
  955                    if let Some(this) = this.upgrade() {
  956                        this.update(cx, |_, cx| {
  957                            cx.emit(LspStoreEvent::LanguageServerLog(
  958                                server_id,
  959                                LanguageServerLogType::Log(params.typ),
  960                                params.message,
  961                            ));
  962                        })
  963                        .ok();
  964                    }
  965                }
  966            })
  967            .detach();
  968
  969        language_server
  970            .on_notification::<lsp::notification::LogTrace, _>({
  971                let this = this.clone();
  972                move |params, cx| {
  973                    let mut cx = cx.clone();
  974                    if let Some(this) = this.upgrade() {
  975                        this.update(&mut cx, |_, cx| {
  976                            cx.emit(LspStoreEvent::LanguageServerLog(
  977                                server_id,
  978                                LanguageServerLogType::Trace(params.verbose),
  979                                params.message,
  980                            ));
  981                        })
  982                        .ok();
  983                    }
  984                }
  985            })
  986            .detach();
  987
  988        json_language_server_ext::register_requests(this.clone(), language_server);
  989        rust_analyzer_ext::register_notifications(this.clone(), language_server);
  990        clangd_ext::register_notifications(this, language_server, adapter);
  991    }
  992
  993    fn shutdown_language_servers_on_quit(
  994        &mut self,
  995        _: &mut Context<LspStore>,
  996    ) -> impl Future<Output = ()> + use<> {
  997        let shutdown_futures = self
  998            .language_servers
  999            .drain()
 1000            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1001            .collect::<Vec<_>>();
 1002
 1003        async move {
 1004            join_all(shutdown_futures).await;
 1005        }
 1006    }
 1007
 1008    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1009        match server_state {
 1010            LanguageServerState::Running { server, .. } => {
 1011                if let Some(shutdown) = server.shutdown() {
 1012                    shutdown.await;
 1013                }
 1014            }
 1015            LanguageServerState::Starting { startup, .. } => {
 1016                if let Some(server) = startup.await
 1017                    && let Some(shutdown) = server.shutdown() {
 1018                        shutdown.await;
 1019                    }
 1020            }
 1021        }
 1022        Ok(())
 1023    }
 1024
 1025    fn language_servers_for_worktree(
 1026        &self,
 1027        worktree_id: WorktreeId,
 1028    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1029        self.language_server_ids
 1030            .iter()
 1031            .filter_map(move |(seed, state)| {
 1032                if seed.worktree_id != worktree_id {
 1033                    return None;
 1034                }
 1035
 1036                if let Some(LanguageServerState::Running { server, .. }) =
 1037                    self.language_servers.get(&state.id)
 1038                {
 1039                    return Some(server);
 1040                } else {
 1041                    None
 1042                }
 1043            })
 1044    }
 1045
 1046    fn language_server_ids_for_project_path(
 1047        &self,
 1048        project_path: ProjectPath,
 1049        language: &Language,
 1050        cx: &mut App,
 1051    ) -> Vec<LanguageServerId> {
 1052        let Some(worktree) = self
 1053            .worktree_store
 1054            .read(cx)
 1055            .worktree_for_id(project_path.worktree_id, cx)
 1056        else {
 1057            return Vec::new();
 1058        };
 1059        let delegate: Arc<dyn ManifestDelegate> =
 1060            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1061        let root = self
 1062            .lsp_tree
 1063            .get(
 1064                project_path,
 1065                language.name(),
 1066                language.manifest(),
 1067                &delegate,
 1068                cx,
 1069            )
 1070            .collect::<Vec<_>>();
 1071
 1072        root
 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.map_or(false, |provider| provider == &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                            return None;
 2387                        }
 2388                    if let Some(name) = server_node.name()
 2389                        && !only_register_servers.contains(&LanguageServerSelector::Name(name)) {
 2390                            return None;
 2391                        }
 2392                }
 2393
 2394                let server_id = server_node.server_id_or_init(|disposition| {
 2395                    let path = &disposition.path;
 2396                    let server_id = {
 2397                        let uri =
 2398                            Url::from_file_path(worktree.read(cx).abs_path().join(&path.path));
 2399
 2400                        let server_id = self.get_or_insert_language_server(
 2401                            &worktree,
 2402                            delegate.clone(),
 2403                            disposition,
 2404                            &language_name,
 2405                            cx,
 2406                        );
 2407
 2408                        if let Some(state) = self.language_servers.get(&server_id)
 2409                            && let Ok(uri) = uri {
 2410                                state.add_workspace_folder(uri);
 2411                            };
 2412                        server_id
 2413                    };
 2414
 2415                    server_id
 2416                })?;
 2417                let server_state = self.language_servers.get(&server_id)?;
 2418                if let LanguageServerState::Running {
 2419                    server, adapter, ..
 2420                } = server_state
 2421                {
 2422                    Some((server.clone(), adapter.clone()))
 2423                } else {
 2424                    None
 2425                }
 2426            })
 2427            .collect::<Vec<_>>();
 2428        for (server, adapter) in servers_and_adapters {
 2429            buffer_handle.update(cx, |buffer, cx| {
 2430                buffer.set_completion_triggers(
 2431                    server.server_id(),
 2432                    server
 2433                        .capabilities()
 2434                        .completion_provider
 2435                        .as_ref()
 2436                        .and_then(|provider| {
 2437                            provider
 2438                                .trigger_characters
 2439                                .as_ref()
 2440                                .map(|characters| characters.iter().cloned().collect())
 2441                        })
 2442                        .unwrap_or_default(),
 2443                    cx,
 2444                );
 2445            });
 2446
 2447            let snapshot = LspBufferSnapshot {
 2448                version: 0,
 2449                snapshot: initial_snapshot.clone(),
 2450            };
 2451
 2452            let mut registered = false;
 2453            self.buffer_snapshots
 2454                .entry(buffer_id)
 2455                .or_default()
 2456                .entry(server.server_id())
 2457                .or_insert_with(|| {
 2458                    registered = true;
 2459                    server.register_buffer(
 2460                        uri.clone(),
 2461                        adapter.language_id(&language.name()),
 2462                        0,
 2463                        initial_snapshot.text(),
 2464                    );
 2465
 2466                    vec![snapshot]
 2467                });
 2468
 2469            self.buffers_opened_in_servers
 2470                .entry(buffer_id)
 2471                .or_default()
 2472                .insert(server.server_id());
 2473            if registered {
 2474                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2475                    language_server_id: server.server_id(),
 2476                    name: None,
 2477                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2478                        proto::RegisteredForBuffer {
 2479                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2480                            buffer_id: buffer_id.to_proto(),
 2481                        },
 2482                    ),
 2483                });
 2484            }
 2485        }
 2486    }
 2487
 2488    fn reuse_existing_language_server<'lang_name>(
 2489        &self,
 2490        server_tree: &LanguageServerTree,
 2491        worktree: &Entity<Worktree>,
 2492        language_name: &'lang_name LanguageName,
 2493        cx: &mut App,
 2494    ) -> Option<(
 2495        Arc<LocalLspAdapterDelegate>,
 2496        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2497    )> {
 2498        if worktree.read(cx).is_visible() {
 2499            return None;
 2500        }
 2501
 2502        let worktree_store = self.worktree_store.read(cx);
 2503        let servers = server_tree
 2504            .instances
 2505            .iter()
 2506            .filter(|(worktree_id, _)| {
 2507                worktree_store
 2508                    .worktree_for_id(**worktree_id, cx)
 2509                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2510            })
 2511            .flat_map(|(worktree_id, servers)| {
 2512                servers
 2513                    .roots
 2514                    .iter()
 2515                    .flat_map(|(_, language_servers)| language_servers)
 2516                    .map(move |(_, (server_node, server_languages))| {
 2517                        (worktree_id, server_node, server_languages)
 2518                    })
 2519                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2520                    .map(|(worktree_id, server_node, _)| {
 2521                        (
 2522                            *worktree_id,
 2523                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2524                        )
 2525                    })
 2526            })
 2527            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2528                acc.entry(worktree_id)
 2529                    .or_insert_with(Vec::new)
 2530                    .push(server_node);
 2531                acc
 2532            })
 2533            .into_values()
 2534            .max_by_key(|servers| servers.len())?;
 2535
 2536        let worktree_id = worktree.read(cx).id();
 2537        let apply = move |tree: &mut LanguageServerTree| {
 2538            for server_node in &servers {
 2539                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2540            }
 2541            servers
 2542        };
 2543
 2544        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2545        Some((delegate, apply))
 2546    }
 2547
 2548    pub(crate) fn unregister_old_buffer_from_language_servers(
 2549        &mut self,
 2550        buffer: &Entity<Buffer>,
 2551        old_file: &File,
 2552        cx: &mut App,
 2553    ) {
 2554        let old_path = match old_file.as_local() {
 2555            Some(local) => local.abs_path(cx),
 2556            None => return,
 2557        };
 2558
 2559        let Ok(file_url) = lsp::Url::from_file_path(old_path.as_path()) else {
 2560            debug_panic!(
 2561                "`{}` is not parseable as an URI",
 2562                old_path.to_string_lossy()
 2563            );
 2564            return;
 2565        };
 2566        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2567    }
 2568
 2569    pub(crate) fn unregister_buffer_from_language_servers(
 2570        &mut self,
 2571        buffer: &Entity<Buffer>,
 2572        file_url: &lsp::Url,
 2573        cx: &mut App,
 2574    ) {
 2575        buffer.update(cx, |buffer, cx| {
 2576            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2577
 2578            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2579                language_server.unregister_buffer(file_url.clone());
 2580            }
 2581        });
 2582    }
 2583
 2584    fn buffer_snapshot_for_lsp_version(
 2585        &mut self,
 2586        buffer: &Entity<Buffer>,
 2587        server_id: LanguageServerId,
 2588        version: Option<i32>,
 2589        cx: &App,
 2590    ) -> Result<TextBufferSnapshot> {
 2591        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2592
 2593        if let Some(version) = version {
 2594            let buffer_id = buffer.read(cx).remote_id();
 2595            let snapshots = if let Some(snapshots) = self
 2596                .buffer_snapshots
 2597                .get_mut(&buffer_id)
 2598                .and_then(|m| m.get_mut(&server_id))
 2599            {
 2600                snapshots
 2601            } else if version == 0 {
 2602                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2603                // We detect this case and treat it as if the version was `None`.
 2604                return Ok(buffer.read(cx).text_snapshot());
 2605            } else {
 2606                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2607            };
 2608
 2609            let found_snapshot = snapshots
 2610                    .binary_search_by_key(&version, |e| e.version)
 2611                    .map(|ix| snapshots[ix].snapshot.clone())
 2612                    .map_err(|_| {
 2613                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2614                    })?;
 2615
 2616            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2617            Ok(found_snapshot)
 2618        } else {
 2619            Ok((buffer.read(cx)).text_snapshot())
 2620        }
 2621    }
 2622
 2623    async fn get_server_code_actions_from_action_kinds(
 2624        lsp_store: &WeakEntity<LspStore>,
 2625        language_server_id: LanguageServerId,
 2626        code_action_kinds: Vec<lsp::CodeActionKind>,
 2627        buffer: &Entity<Buffer>,
 2628        cx: &mut AsyncApp,
 2629    ) -> Result<Vec<CodeAction>> {
 2630        let actions = lsp_store
 2631            .update(cx, move |this, cx| {
 2632                let request = GetCodeActions {
 2633                    range: text::Anchor::MIN..text::Anchor::MAX,
 2634                    kinds: Some(code_action_kinds),
 2635                };
 2636                let server = LanguageServerToQuery::Other(language_server_id);
 2637                this.request_lsp(buffer.clone(), server, request, cx)
 2638            })?
 2639            .await?;
 2640        return Ok(actions);
 2641    }
 2642
 2643    pub async fn execute_code_actions_on_server(
 2644        lsp_store: &WeakEntity<LspStore>,
 2645        language_server: &Arc<LanguageServer>,
 2646
 2647        actions: Vec<CodeAction>,
 2648        push_to_history: bool,
 2649        project_transaction: &mut ProjectTransaction,
 2650        cx: &mut AsyncApp,
 2651    ) -> anyhow::Result<()> {
 2652        for mut action in actions {
 2653            Self::try_resolve_code_action(language_server, &mut action)
 2654                .await
 2655                .context("resolving a formatting code action")?;
 2656
 2657            if let Some(edit) = action.lsp_action.edit() {
 2658                if edit.changes.is_none() && edit.document_changes.is_none() {
 2659                    continue;
 2660                }
 2661
 2662                let new = Self::deserialize_workspace_edit(
 2663                    lsp_store.upgrade().context("project dropped")?,
 2664                    edit.clone(),
 2665                    push_to_history,
 2666                    language_server.clone(),
 2667                    cx,
 2668                )
 2669                .await?;
 2670                project_transaction.0.extend(new.0);
 2671            }
 2672
 2673            if let Some(command) = action.lsp_action.command() {
 2674                let server_capabilities = language_server.capabilities();
 2675                let available_commands = server_capabilities
 2676                    .execute_command_provider
 2677                    .as_ref()
 2678                    .map(|options| options.commands.as_slice())
 2679                    .unwrap_or_default();
 2680                if available_commands.contains(&command.command) {
 2681                    lsp_store.update(cx, |lsp_store, _| {
 2682                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2683                            mode.last_workspace_edits_by_language_server
 2684                                .remove(&language_server.server_id());
 2685                        }
 2686                    })?;
 2687
 2688                    language_server
 2689                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2690                            command: command.command.clone(),
 2691                            arguments: command.arguments.clone().unwrap_or_default(),
 2692                            ..Default::default()
 2693                        })
 2694                        .await
 2695                        .into_response()
 2696                        .context("execute command")?;
 2697
 2698                    lsp_store.update(cx, |this, _| {
 2699                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2700                            project_transaction.0.extend(
 2701                                mode.last_workspace_edits_by_language_server
 2702                                    .remove(&language_server.server_id())
 2703                                    .unwrap_or_default()
 2704                                    .0,
 2705                            )
 2706                        }
 2707                    })?;
 2708                } else {
 2709                    log::warn!(
 2710                        "Cannot execute a command {} not listed in the language server capabilities",
 2711                        command.command
 2712                    )
 2713                }
 2714            }
 2715        }
 2716        return Ok(());
 2717    }
 2718
 2719    pub async fn deserialize_text_edits(
 2720        this: Entity<LspStore>,
 2721        buffer_to_edit: Entity<Buffer>,
 2722        edits: Vec<lsp::TextEdit>,
 2723        push_to_history: bool,
 2724        _: Arc<CachedLspAdapter>,
 2725        language_server: Arc<LanguageServer>,
 2726        cx: &mut AsyncApp,
 2727    ) -> Result<Option<Transaction>> {
 2728        let edits = this
 2729            .update(cx, |this, cx| {
 2730                this.as_local_mut().unwrap().edits_from_lsp(
 2731                    &buffer_to_edit,
 2732                    edits,
 2733                    language_server.server_id(),
 2734                    None,
 2735                    cx,
 2736                )
 2737            })?
 2738            .await?;
 2739
 2740        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2741            buffer.finalize_last_transaction();
 2742            buffer.start_transaction();
 2743            for (range, text) in edits {
 2744                buffer.edit([(range, text)], None, cx);
 2745            }
 2746
 2747            if buffer.end_transaction(cx).is_some() {
 2748                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2749                if !push_to_history {
 2750                    buffer.forget_transaction(transaction.id);
 2751                }
 2752                Some(transaction)
 2753            } else {
 2754                None
 2755            }
 2756        })?;
 2757
 2758        Ok(transaction)
 2759    }
 2760
 2761    #[allow(clippy::type_complexity)]
 2762    pub(crate) fn edits_from_lsp(
 2763        &mut self,
 2764        buffer: &Entity<Buffer>,
 2765        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2766        server_id: LanguageServerId,
 2767        version: Option<i32>,
 2768        cx: &mut Context<LspStore>,
 2769    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2770        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2771        cx.background_spawn(async move {
 2772            let snapshot = snapshot?;
 2773            let mut lsp_edits = lsp_edits
 2774                .into_iter()
 2775                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2776                .collect::<Vec<_>>();
 2777
 2778            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2779
 2780            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2781            let mut edits = Vec::new();
 2782            while let Some((range, mut new_text)) = lsp_edits.next() {
 2783                // Clip invalid ranges provided by the language server.
 2784                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2785                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2786
 2787                // Combine any LSP edits that are adjacent.
 2788                //
 2789                // Also, combine LSP edits that are separated from each other by only
 2790                // a newline. This is important because for some code actions,
 2791                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2792                // are separated by unchanged newline characters.
 2793                //
 2794                // In order for the diffing logic below to work properly, any edits that
 2795                // cancel each other out must be combined into one.
 2796                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2797                    if next_range.start.0 > range.end {
 2798                        if next_range.start.0.row > range.end.row + 1
 2799                            || next_range.start.0.column > 0
 2800                            || snapshot.clip_point_utf16(
 2801                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2802                                Bias::Left,
 2803                            ) > range.end
 2804                        {
 2805                            break;
 2806                        }
 2807                        new_text.push('\n');
 2808                    }
 2809                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2810                    new_text.push_str(next_text);
 2811                    lsp_edits.next();
 2812                }
 2813
 2814                // For multiline edits, perform a diff of the old and new text so that
 2815                // we can identify the changes more precisely, preserving the locations
 2816                // of any anchors positioned in the unchanged regions.
 2817                if range.end.row > range.start.row {
 2818                    let offset = range.start.to_offset(&snapshot);
 2819                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2820                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2821                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2822                        (
 2823                            snapshot.anchor_after(offset + range.start)
 2824                                ..snapshot.anchor_before(offset + range.end),
 2825                            replacement,
 2826                        )
 2827                    }));
 2828                } else if range.end == range.start {
 2829                    let anchor = snapshot.anchor_after(range.start);
 2830                    edits.push((anchor..anchor, new_text.into()));
 2831                } else {
 2832                    let edit_start = snapshot.anchor_after(range.start);
 2833                    let edit_end = snapshot.anchor_before(range.end);
 2834                    edits.push((edit_start..edit_end, new_text.into()));
 2835                }
 2836            }
 2837
 2838            Ok(edits)
 2839        })
 2840    }
 2841
 2842    pub(crate) async fn deserialize_workspace_edit(
 2843        this: Entity<LspStore>,
 2844        edit: lsp::WorkspaceEdit,
 2845        push_to_history: bool,
 2846        language_server: Arc<LanguageServer>,
 2847        cx: &mut AsyncApp,
 2848    ) -> Result<ProjectTransaction> {
 2849        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2850
 2851        let mut operations = Vec::new();
 2852        if let Some(document_changes) = edit.document_changes {
 2853            match document_changes {
 2854                lsp::DocumentChanges::Edits(edits) => {
 2855                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2856                }
 2857                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2858            }
 2859        } else if let Some(changes) = edit.changes {
 2860            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2861                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2862                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2863                        uri,
 2864                        version: None,
 2865                    },
 2866                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2867                })
 2868            }));
 2869        }
 2870
 2871        let mut project_transaction = ProjectTransaction::default();
 2872        for operation in operations {
 2873            match operation {
 2874                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2875                    let abs_path = op
 2876                        .uri
 2877                        .to_file_path()
 2878                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2879
 2880                    if let Some(parent_path) = abs_path.parent() {
 2881                        fs.create_dir(parent_path).await?;
 2882                    }
 2883                    if abs_path.ends_with("/") {
 2884                        fs.create_dir(&abs_path).await?;
 2885                    } else {
 2886                        fs.create_file(
 2887                            &abs_path,
 2888                            op.options
 2889                                .map(|options| fs::CreateOptions {
 2890                                    overwrite: options.overwrite.unwrap_or(false),
 2891                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2892                                })
 2893                                .unwrap_or_default(),
 2894                        )
 2895                        .await?;
 2896                    }
 2897                }
 2898
 2899                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2900                    let source_abs_path = op
 2901                        .old_uri
 2902                        .to_file_path()
 2903                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2904                    let target_abs_path = op
 2905                        .new_uri
 2906                        .to_file_path()
 2907                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2908                    fs.rename(
 2909                        &source_abs_path,
 2910                        &target_abs_path,
 2911                        op.options
 2912                            .map(|options| fs::RenameOptions {
 2913                                overwrite: options.overwrite.unwrap_or(false),
 2914                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2915                            })
 2916                            .unwrap_or_default(),
 2917                    )
 2918                    .await?;
 2919                }
 2920
 2921                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2922                    let abs_path = op
 2923                        .uri
 2924                        .to_file_path()
 2925                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2926                    let options = op
 2927                        .options
 2928                        .map(|options| fs::RemoveOptions {
 2929                            recursive: options.recursive.unwrap_or(false),
 2930                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2931                        })
 2932                        .unwrap_or_default();
 2933                    if abs_path.ends_with("/") {
 2934                        fs.remove_dir(&abs_path, options).await?;
 2935                    } else {
 2936                        fs.remove_file(&abs_path, options).await?;
 2937                    }
 2938                }
 2939
 2940                lsp::DocumentChangeOperation::Edit(op) => {
 2941                    let buffer_to_edit = this
 2942                        .update(cx, |this, cx| {
 2943                            this.open_local_buffer_via_lsp(
 2944                                op.text_document.uri.clone(),
 2945                                language_server.server_id(),
 2946                                cx,
 2947                            )
 2948                        })?
 2949                        .await?;
 2950
 2951                    let edits = this
 2952                        .update(cx, |this, cx| {
 2953                            let path = buffer_to_edit.read(cx).project_path(cx);
 2954                            let active_entry = this.active_entry;
 2955                            let is_active_entry = path.clone().map_or(false, |project_path| {
 2956                                this.worktree_store
 2957                                    .read(cx)
 2958                                    .entry_for_path(&project_path, cx)
 2959                                    .map_or(false, |entry| Some(entry.id) == active_entry)
 2960                            });
 2961                            let local = this.as_local_mut().unwrap();
 2962
 2963                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2964                            for edit in op.edits {
 2965                                match edit {
 2966                                    Edit::Plain(edit) => {
 2967                                        if !edits.contains(&edit) {
 2968                                            edits.push(edit)
 2969                                        }
 2970                                    }
 2971                                    Edit::Annotated(edit) => {
 2972                                        if !edits.contains(&edit.text_edit) {
 2973                                            edits.push(edit.text_edit)
 2974                                        }
 2975                                    }
 2976                                    Edit::Snippet(edit) => {
 2977                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2978                                        else {
 2979                                            continue;
 2980                                        };
 2981
 2982                                        if is_active_entry {
 2983                                            snippet_edits.push((edit.range, snippet));
 2984                                        } else {
 2985                                            // Since this buffer is not focused, apply a normal edit.
 2986                                            let new_edit = TextEdit {
 2987                                                range: edit.range,
 2988                                                new_text: snippet.text,
 2989                                            };
 2990                                            if !edits.contains(&new_edit) {
 2991                                                edits.push(new_edit);
 2992                                            }
 2993                                        }
 2994                                    }
 2995                                }
 2996                            }
 2997                            if !snippet_edits.is_empty() {
 2998                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 2999                                let version = if let Some(buffer_version) = op.text_document.version
 3000                                {
 3001                                    local
 3002                                        .buffer_snapshot_for_lsp_version(
 3003                                            &buffer_to_edit,
 3004                                            language_server.server_id(),
 3005                                            Some(buffer_version),
 3006                                            cx,
 3007                                        )
 3008                                        .ok()
 3009                                        .map(|snapshot| snapshot.version)
 3010                                } else {
 3011                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3012                                };
 3013
 3014                                let most_recent_edit = version.and_then(|version| {
 3015                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3016                                });
 3017                                // Check if the edit that triggered that edit has been made by this participant.
 3018
 3019                                if let Some(most_recent_edit) = most_recent_edit {
 3020                                    cx.emit(LspStoreEvent::SnippetEdit {
 3021                                        buffer_id,
 3022                                        edits: snippet_edits,
 3023                                        most_recent_edit,
 3024                                    });
 3025                                }
 3026                            }
 3027
 3028                            local.edits_from_lsp(
 3029                                &buffer_to_edit,
 3030                                edits,
 3031                                language_server.server_id(),
 3032                                op.text_document.version,
 3033                                cx,
 3034                            )
 3035                        })?
 3036                        .await?;
 3037
 3038                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3039                        buffer.finalize_last_transaction();
 3040                        buffer.start_transaction();
 3041                        for (range, text) in edits {
 3042                            buffer.edit([(range, text)], None, cx);
 3043                        }
 3044
 3045                        let transaction = buffer.end_transaction(cx).and_then(|transaction_id| {
 3046                            if push_to_history {
 3047                                buffer.finalize_last_transaction();
 3048                                buffer.get_transaction(transaction_id).cloned()
 3049                            } else {
 3050                                buffer.forget_transaction(transaction_id)
 3051                            }
 3052                        });
 3053
 3054                        transaction
 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                        local.reset_buffer(buffer, old_file, cx);
 3844
 3845                        if local.registered_buffers.contains_key(&buffer_id) {
 3846                            local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3847                        }
 3848                    }
 3849
 3850                self.detect_language_for_buffer(buffer, cx);
 3851                if let Some(local) = self.as_local_mut() {
 3852                    local.initialize_buffer(buffer, cx);
 3853                    if local.registered_buffers.contains_key(&buffer_id) {
 3854                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3855                    }
 3856                }
 3857            }
 3858            _ => {}
 3859        }
 3860    }
 3861
 3862    fn on_worktree_store_event(
 3863        &mut self,
 3864        _: Entity<WorktreeStore>,
 3865        event: &WorktreeStoreEvent,
 3866        cx: &mut Context<Self>,
 3867    ) {
 3868        match event {
 3869            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3870                if !worktree.read(cx).is_local() {
 3871                    return;
 3872                }
 3873                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3874                    worktree::Event::UpdatedEntries(changes) => {
 3875                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3876                    }
 3877                    worktree::Event::UpdatedGitRepositories(_)
 3878                    | worktree::Event::DeletedEntry(_) => {}
 3879                })
 3880                .detach()
 3881            }
 3882            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3883            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3884                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3885            }
 3886            WorktreeStoreEvent::WorktreeReleased(..)
 3887            | WorktreeStoreEvent::WorktreeOrderChanged
 3888            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3889            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3890            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3891        }
 3892    }
 3893
 3894    fn on_prettier_store_event(
 3895        &mut self,
 3896        _: Entity<PrettierStore>,
 3897        event: &PrettierStoreEvent,
 3898        cx: &mut Context<Self>,
 3899    ) {
 3900        match event {
 3901            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3902                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3903            }
 3904            PrettierStoreEvent::LanguageServerAdded {
 3905                new_server_id,
 3906                name,
 3907                prettier_server,
 3908            } => {
 3909                self.register_supplementary_language_server(
 3910                    *new_server_id,
 3911                    name.clone(),
 3912                    prettier_server.clone(),
 3913                    cx,
 3914                );
 3915            }
 3916        }
 3917    }
 3918
 3919    fn on_toolchain_store_event(
 3920        &mut self,
 3921        _: Entity<LocalToolchainStore>,
 3922        event: &ToolchainStoreEvent,
 3923        _: &mut Context<Self>,
 3924    ) {
 3925        match event {
 3926            ToolchainStoreEvent::ToolchainActivated { .. } => {
 3927                self.request_workspace_config_refresh()
 3928            }
 3929        }
 3930    }
 3931
 3932    fn request_workspace_config_refresh(&mut self) {
 3933        *self._maintain_workspace_config.1.borrow_mut() = ();
 3934    }
 3935
 3936    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3937        self.as_local().map(|local| local.prettier_store.clone())
 3938    }
 3939
 3940    fn on_buffer_event(
 3941        &mut self,
 3942        buffer: Entity<Buffer>,
 3943        event: &language::BufferEvent,
 3944        cx: &mut Context<Self>,
 3945    ) {
 3946        match event {
 3947            language::BufferEvent::Edited => {
 3948                self.on_buffer_edited(buffer, cx);
 3949            }
 3950
 3951            language::BufferEvent::Saved => {
 3952                self.on_buffer_saved(buffer, cx);
 3953            }
 3954
 3955            _ => {}
 3956        }
 3957    }
 3958
 3959    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3960        buffer
 3961            .read(cx)
 3962            .set_language_registry(self.languages.clone());
 3963
 3964        cx.subscribe(buffer, |this, buffer, event, cx| {
 3965            this.on_buffer_event(buffer, event, cx);
 3966        })
 3967        .detach();
 3968
 3969        self.detect_language_for_buffer(buffer, cx);
 3970        if let Some(local) = self.as_local_mut() {
 3971            local.initialize_buffer(buffer, cx);
 3972        }
 3973
 3974        Ok(())
 3975    }
 3976
 3977    pub fn reload_zed_json_schemas_on_extensions_changed(
 3978        &mut self,
 3979        _: Entity<extension::ExtensionEvents>,
 3980        evt: &extension::Event,
 3981        cx: &mut Context<Self>,
 3982    ) {
 3983        match evt {
 3984            extension::Event::ExtensionInstalled(_)
 3985            | extension::Event::ExtensionUninstalled(_)
 3986            | extension::Event::ConfigureExtensionRequested(_) => return,
 3987            extension::Event::ExtensionsInstalledChanged => {}
 3988        }
 3989        if self.as_local().is_none() {
 3990            return;
 3991        }
 3992        cx.spawn(async move |this, cx| {
 3993            let weak_ref = this.clone();
 3994
 3995            let servers = this
 3996                .update(cx, |this, cx| {
 3997                    let local = this.as_local()?;
 3998
 3999                    let mut servers = Vec::new();
 4000                    for (seed, state) in &local.language_server_ids {
 4001
 4002                            let Some(states) = local.language_servers.get(&state.id) else {
 4003                                continue;
 4004                            };
 4005                            let (json_adapter, json_server) = match states {
 4006                                LanguageServerState::Running {
 4007                                    adapter, server, ..
 4008                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 4009                                    (adapter.adapter.clone(), server.clone())
 4010                                }
 4011                                _ => continue,
 4012                            };
 4013
 4014                            let Some(worktree) = this
 4015                                .worktree_store
 4016                                .read(cx)
 4017                                .worktree_for_id(seed.worktree_id, cx)
 4018                            else {
 4019                                continue;
 4020                            };
 4021                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4022                                LocalLspAdapterDelegate::new(
 4023                                    local.languages.clone(),
 4024                                    &local.environment,
 4025                                    weak_ref.clone(),
 4026                                    &worktree,
 4027                                    local.http_client.clone(),
 4028                                    local.fs.clone(),
 4029                                    cx,
 4030                                );
 4031
 4032                            servers.push((json_adapter, json_server, json_delegate));
 4033
 4034                    }
 4035                    return Some(servers);
 4036                })
 4037                .ok()
 4038                .flatten();
 4039
 4040            let Some(servers) = servers else {
 4041                return;
 4042            };
 4043
 4044            let Ok(Some((fs, _))) = this.read_with(cx, |this, _| {
 4045                let local = this.as_local()?;
 4046                let toolchain_store = local.toolchain_store().clone();
 4047                return Some((local.fs.clone(), toolchain_store));
 4048            }) else {
 4049                return;
 4050            };
 4051            for (adapter, server, delegate) in servers {
 4052                adapter.clear_zed_json_schema_cache().await;
 4053
 4054                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4055                        adapter,
 4056                        fs.as_ref(),
 4057                        &delegate,
 4058                        None,
 4059                        cx,
 4060                    )
 4061                    .await
 4062                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4063                    .ok()
 4064                else {
 4065                    continue;
 4066                };
 4067                server
 4068                    .notify::<lsp::notification::DidChangeConfiguration>(
 4069                        &lsp::DidChangeConfigurationParams {
 4070                            settings: json_workspace_config,
 4071                        },
 4072                    )
 4073                    .ok();
 4074            }
 4075        })
 4076        .detach();
 4077    }
 4078
 4079    pub(crate) fn register_buffer_with_language_servers(
 4080        &mut self,
 4081        buffer: &Entity<Buffer>,
 4082        only_register_servers: HashSet<LanguageServerSelector>,
 4083        ignore_refcounts: bool,
 4084        cx: &mut Context<Self>,
 4085    ) -> OpenLspBufferHandle {
 4086        let buffer_id = buffer.read(cx).remote_id();
 4087        let handle = cx.new(|_| buffer.clone());
 4088        if let Some(local) = self.as_local_mut() {
 4089            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4090            if !ignore_refcounts {
 4091                *refcount += 1;
 4092            }
 4093
 4094            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4095            // 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
 4096            // 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
 4097            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4098            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4099                return handle;
 4100            };
 4101            if !file.is_local() {
 4102                return handle;
 4103            }
 4104
 4105            if ignore_refcounts || *refcount == 1 {
 4106                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4107            }
 4108            if !ignore_refcounts {
 4109                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4110                    let refcount = {
 4111                        let local = lsp_store.as_local_mut().unwrap();
 4112                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4113                            debug_panic!("bad refcounting");
 4114                            return;
 4115                        };
 4116
 4117                        *refcount -= 1;
 4118                        *refcount
 4119                    };
 4120                    if refcount == 0 {
 4121                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4122                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4123                        let local = lsp_store.as_local_mut().unwrap();
 4124                        local.registered_buffers.remove(&buffer_id);
 4125                        local.buffers_opened_in_servers.remove(&buffer_id);
 4126                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4127                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4128                        }
 4129                    }
 4130                })
 4131                .detach();
 4132            }
 4133        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4134            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4135            cx.background_spawn(async move {
 4136                upstream_client
 4137                    .request(proto::RegisterBufferWithLanguageServers {
 4138                        project_id: upstream_project_id,
 4139                        buffer_id,
 4140                        only_servers: only_register_servers
 4141                            .into_iter()
 4142                            .map(|selector| {
 4143                                let selector = match selector {
 4144                                    LanguageServerSelector::Id(language_server_id) => {
 4145                                        proto::language_server_selector::Selector::ServerId(
 4146                                            language_server_id.to_proto(),
 4147                                        )
 4148                                    }
 4149                                    LanguageServerSelector::Name(language_server_name) => {
 4150                                        proto::language_server_selector::Selector::Name(
 4151                                            language_server_name.to_string(),
 4152                                        )
 4153                                    }
 4154                                };
 4155                                proto::LanguageServerSelector {
 4156                                    selector: Some(selector),
 4157                                }
 4158                            })
 4159                            .collect(),
 4160                    })
 4161                    .await
 4162            })
 4163            .detach();
 4164        } else {
 4165            panic!("oops!");
 4166        }
 4167        handle
 4168    }
 4169
 4170    fn maintain_buffer_languages(
 4171        languages: Arc<LanguageRegistry>,
 4172        cx: &mut Context<Self>,
 4173    ) -> Task<()> {
 4174        let mut subscription = languages.subscribe();
 4175        let mut prev_reload_count = languages.reload_count();
 4176        cx.spawn(async move |this, cx| {
 4177            while let Some(()) = subscription.next().await {
 4178                if let Some(this) = this.upgrade() {
 4179                    // If the language registry has been reloaded, then remove and
 4180                    // re-assign the languages on all open buffers.
 4181                    let reload_count = languages.reload_count();
 4182                    if reload_count > prev_reload_count {
 4183                        prev_reload_count = reload_count;
 4184                        this.update(cx, |this, cx| {
 4185                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4186                                for buffer in buffer_store.buffers() {
 4187                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4188                                    {
 4189                                        buffer
 4190                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4191                                        if let Some(local) = this.as_local_mut() {
 4192                                            local.reset_buffer(&buffer, &f, cx);
 4193
 4194                                            if local
 4195                                                .registered_buffers
 4196                                                .contains_key(&buffer.read(cx).remote_id())
 4197                                                && let Some(file_url) =
 4198                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4199                                                {
 4200                                                    local.unregister_buffer_from_language_servers(
 4201                                                        &buffer, &file_url, cx,
 4202                                                    );
 4203                                                }
 4204                                        }
 4205                                    }
 4206                                }
 4207                            });
 4208                        })
 4209                        .ok();
 4210                    }
 4211
 4212                    this.update(cx, |this, cx| {
 4213                        let mut plain_text_buffers = Vec::new();
 4214                        let mut buffers_with_unknown_injections = Vec::new();
 4215                        for handle in this.buffer_store.read(cx).buffers() {
 4216                            let buffer = handle.read(cx);
 4217                            if buffer.language().is_none()
 4218                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4219                            {
 4220                                plain_text_buffers.push(handle);
 4221                            } else if buffer.contains_unknown_injections() {
 4222                                buffers_with_unknown_injections.push(handle);
 4223                            }
 4224                        }
 4225
 4226                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4227                        // and reused later in the invisible worktrees.
 4228                        plain_text_buffers.sort_by_key(|buffer| {
 4229                            Reverse(
 4230                                File::from_dyn(buffer.read(cx).file())
 4231                                    .map(|file| file.worktree.read(cx).is_visible()),
 4232                            )
 4233                        });
 4234
 4235                        for buffer in plain_text_buffers {
 4236                            this.detect_language_for_buffer(&buffer, cx);
 4237                            if let Some(local) = this.as_local_mut() {
 4238                                local.initialize_buffer(&buffer, cx);
 4239                                if local
 4240                                    .registered_buffers
 4241                                    .contains_key(&buffer.read(cx).remote_id())
 4242                                {
 4243                                    local.register_buffer_with_language_servers(
 4244                                        &buffer,
 4245                                        HashSet::default(),
 4246                                        cx,
 4247                                    );
 4248                                }
 4249                            }
 4250                        }
 4251
 4252                        for buffer in buffers_with_unknown_injections {
 4253                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4254                        }
 4255                    })
 4256                    .ok();
 4257                }
 4258            }
 4259        })
 4260    }
 4261
 4262    fn detect_language_for_buffer(
 4263        &mut self,
 4264        buffer_handle: &Entity<Buffer>,
 4265        cx: &mut Context<Self>,
 4266    ) -> Option<language::AvailableLanguage> {
 4267        // If the buffer has a language, set it and start the language server if we haven't already.
 4268        let buffer = buffer_handle.read(cx);
 4269        let file = buffer.file()?;
 4270
 4271        let content = buffer.as_rope();
 4272        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4273        if let Some(available_language) = &available_language {
 4274            if let Some(Ok(Ok(new_language))) = self
 4275                .languages
 4276                .load_language(available_language)
 4277                .now_or_never()
 4278            {
 4279                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4280            }
 4281        } else {
 4282            cx.emit(LspStoreEvent::LanguageDetected {
 4283                buffer: buffer_handle.clone(),
 4284                new_language: None,
 4285            });
 4286        }
 4287
 4288        available_language
 4289    }
 4290
 4291    pub(crate) fn set_language_for_buffer(
 4292        &mut self,
 4293        buffer_entity: &Entity<Buffer>,
 4294        new_language: Arc<Language>,
 4295        cx: &mut Context<Self>,
 4296    ) {
 4297        let buffer = buffer_entity.read(cx);
 4298        let buffer_file = buffer.file().cloned();
 4299        let buffer_id = buffer.remote_id();
 4300        if let Some(local_store) = self.as_local_mut()
 4301            && local_store.registered_buffers.contains_key(&buffer_id)
 4302                && let Some(abs_path) =
 4303                    File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4304                    && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err() {
 4305                        local_store.unregister_buffer_from_language_servers(
 4306                            buffer_entity,
 4307                            &file_url,
 4308                            cx,
 4309                        );
 4310                    }
 4311        buffer_entity.update(cx, |buffer, cx| {
 4312            if buffer.language().map_or(true, |old_language| {
 4313                !Arc::ptr_eq(old_language, &new_language)
 4314            }) {
 4315                buffer.set_language(Some(new_language.clone()), cx);
 4316            }
 4317        });
 4318
 4319        let settings =
 4320            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4321        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4322
 4323        let worktree_id = if let Some(file) = buffer_file {
 4324            let worktree = file.worktree.clone();
 4325
 4326            if let Some(local) = self.as_local_mut()
 4327                && local.registered_buffers.contains_key(&buffer_id) {
 4328                    local.register_buffer_with_language_servers(
 4329                        buffer_entity,
 4330                        HashSet::default(),
 4331                        cx,
 4332                    );
 4333                }
 4334            Some(worktree.read(cx).id())
 4335        } else {
 4336            None
 4337        };
 4338
 4339        if settings.prettier.allowed
 4340            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4341            {
 4342                let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4343                if let Some(prettier_store) = prettier_store {
 4344                    prettier_store.update(cx, |prettier_store, cx| {
 4345                        prettier_store.install_default_prettier(
 4346                            worktree_id,
 4347                            prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4348                            cx,
 4349                        )
 4350                    })
 4351                }
 4352            }
 4353
 4354        cx.emit(LspStoreEvent::LanguageDetected {
 4355            buffer: buffer_entity.clone(),
 4356            new_language: Some(new_language),
 4357        })
 4358    }
 4359
 4360    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4361        self.buffer_store.clone()
 4362    }
 4363
 4364    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4365        self.active_entry = active_entry;
 4366    }
 4367
 4368    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4369        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4370            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id()) {
 4371                let mut summaries =
 4372                    diangostic_summaries
 4373                        .into_iter()
 4374                        .flat_map(|(path, summaries)| {
 4375                            summaries
 4376                                .into_iter()
 4377                                .map(|(server_id, summary)| summary.to_proto(*server_id, path))
 4378                        });
 4379                if let Some(summary) = summaries.next() {
 4380                    client
 4381                        .send(proto::UpdateDiagnosticSummary {
 4382                            project_id: downstream_project_id,
 4383                            worktree_id: worktree.id().to_proto(),
 4384                            summary: Some(summary),
 4385                            more_summaries: summaries.collect(),
 4386                        })
 4387                        .log_err();
 4388                }
 4389            }
 4390    }
 4391
 4392    // TODO: remove MultiLspQuery: instead, the proto handler should pick appropriate server(s)
 4393    // Then, use `send_lsp_proto_request` or analogue for most of the LSP proto requests and inline this check inside
 4394    fn is_capable_for_proto_request<R>(
 4395        &self,
 4396        buffer: &Entity<Buffer>,
 4397        request: &R,
 4398        cx: &Context<Self>,
 4399    ) -> bool
 4400    where
 4401        R: LspCommand,
 4402    {
 4403        self.check_if_capable_for_proto_request(
 4404            buffer,
 4405            |capabilities| {
 4406                request.check_capabilities(AdapterServerCapabilities {
 4407                    server_capabilities: capabilities.clone(),
 4408                    code_action_kinds: None,
 4409                })
 4410            },
 4411            cx,
 4412        )
 4413    }
 4414
 4415    fn check_if_capable_for_proto_request<F>(
 4416        &self,
 4417        buffer: &Entity<Buffer>,
 4418        check: F,
 4419        cx: &Context<Self>,
 4420    ) -> bool
 4421    where
 4422        F: Fn(&lsp::ServerCapabilities) -> bool,
 4423    {
 4424        let Some(language) = buffer.read(cx).language().cloned() else {
 4425            return false;
 4426        };
 4427        let relevant_language_servers = self
 4428            .languages
 4429            .lsp_adapters(&language.name())
 4430            .into_iter()
 4431            .map(|lsp_adapter| lsp_adapter.name())
 4432            .collect::<HashSet<_>>();
 4433        self.language_server_statuses
 4434            .iter()
 4435            .filter_map(|(server_id, server_status)| {
 4436                relevant_language_servers
 4437                    .contains(&server_status.name)
 4438                    .then_some(server_id)
 4439            })
 4440            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4441            .any(check)
 4442    }
 4443
 4444    pub fn request_lsp<R>(
 4445        &mut self,
 4446        buffer: Entity<Buffer>,
 4447        server: LanguageServerToQuery,
 4448        request: R,
 4449        cx: &mut Context<Self>,
 4450    ) -> Task<Result<R::Response>>
 4451    where
 4452        R: LspCommand,
 4453        <R::LspRequest as lsp::request::Request>::Result: Send,
 4454        <R::LspRequest as lsp::request::Request>::Params: Send,
 4455    {
 4456        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4457            return self.send_lsp_proto_request(
 4458                buffer,
 4459                upstream_client,
 4460                upstream_project_id,
 4461                request,
 4462                cx,
 4463            );
 4464        }
 4465
 4466        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4467            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4468                local
 4469                    .language_servers_for_buffer(buffer, cx)
 4470                    .find(|(_, server)| {
 4471                        request.check_capabilities(server.adapter_server_capabilities())
 4472                    })
 4473                    .map(|(_, server)| server.clone())
 4474            }),
 4475            LanguageServerToQuery::Other(id) => self
 4476                .language_server_for_local_buffer(buffer, id, cx)
 4477                .and_then(|(_, server)| {
 4478                    request
 4479                        .check_capabilities(server.adapter_server_capabilities())
 4480                        .then(|| Arc::clone(server))
 4481                }),
 4482        }) else {
 4483            return Task::ready(Ok(Default::default()));
 4484        };
 4485
 4486        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4487
 4488        let Some(file) = file else {
 4489            return Task::ready(Ok(Default::default()));
 4490        };
 4491
 4492        let lsp_params = match request.to_lsp_params_or_response(
 4493            &file.abs_path(cx),
 4494            buffer.read(cx),
 4495            &language_server,
 4496            cx,
 4497        ) {
 4498            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4499            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4500
 4501            Err(err) => {
 4502                let message = format!(
 4503                    "{} via {} failed: {}",
 4504                    request.display_name(),
 4505                    language_server.name(),
 4506                    err
 4507                );
 4508                log::warn!("{message}");
 4509                return Task::ready(Err(anyhow!(message)));
 4510            }
 4511        };
 4512
 4513        let status = request.status();
 4514        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4515            return Task::ready(Ok(Default::default()));
 4516        }
 4517        return cx.spawn(async move |this, cx| {
 4518            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4519
 4520            let id = lsp_request.id();
 4521            let _cleanup = if status.is_some() {
 4522                cx.update(|cx| {
 4523                    this.update(cx, |this, cx| {
 4524                        this.on_lsp_work_start(
 4525                            language_server.server_id(),
 4526                            id.to_string(),
 4527                            LanguageServerProgress {
 4528                                is_disk_based_diagnostics_progress: false,
 4529                                is_cancellable: false,
 4530                                title: None,
 4531                                message: status.clone(),
 4532                                percentage: None,
 4533                                last_update_at: cx.background_executor().now(),
 4534                            },
 4535                            cx,
 4536                        );
 4537                    })
 4538                })
 4539                .log_err();
 4540
 4541                Some(defer(|| {
 4542                    cx.update(|cx| {
 4543                        this.update(cx, |this, cx| {
 4544                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4545                        })
 4546                    })
 4547                    .log_err();
 4548                }))
 4549            } else {
 4550                None
 4551            };
 4552
 4553            let result = lsp_request.await.into_response();
 4554
 4555            let response = result.map_err(|err| {
 4556                let message = format!(
 4557                    "{} via {} failed: {}",
 4558                    request.display_name(),
 4559                    language_server.name(),
 4560                    err
 4561                );
 4562                log::warn!("{message}");
 4563                anyhow::anyhow!(message)
 4564            })?;
 4565
 4566            let response = request
 4567                .response_from_lsp(
 4568                    response,
 4569                    this.upgrade().context("no app context")?,
 4570                    buffer,
 4571                    language_server.server_id(),
 4572                    cx.clone(),
 4573                )
 4574                .await;
 4575            response
 4576        });
 4577    }
 4578
 4579    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4580        let mut language_formatters_to_check = Vec::new();
 4581        for buffer in self.buffer_store.read(cx).buffers() {
 4582            let buffer = buffer.read(cx);
 4583            let buffer_file = File::from_dyn(buffer.file());
 4584            let buffer_language = buffer.language();
 4585            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4586            if buffer_language.is_some() {
 4587                language_formatters_to_check.push((
 4588                    buffer_file.map(|f| f.worktree_id(cx)),
 4589                    settings.into_owned(),
 4590                ));
 4591            }
 4592        }
 4593
 4594        self.request_workspace_config_refresh();
 4595
 4596        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4597            prettier_store.update(cx, |prettier_store, cx| {
 4598                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4599            })
 4600        }
 4601
 4602        cx.notify();
 4603    }
 4604
 4605    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4606        let buffer_store = self.buffer_store.clone();
 4607        let Some(local) = self.as_local_mut() else {
 4608            return;
 4609        };
 4610        let mut adapters = BTreeMap::default();
 4611        let get_adapter = {
 4612            let languages = local.languages.clone();
 4613            let environment = local.environment.clone();
 4614            let weak = local.weak.clone();
 4615            let worktree_store = local.worktree_store.clone();
 4616            let http_client = local.http_client.clone();
 4617            let fs = local.fs.clone();
 4618            move |worktree_id, cx: &mut App| {
 4619                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4620                Some(LocalLspAdapterDelegate::new(
 4621                    languages.clone(),
 4622                    &environment,
 4623                    weak.clone(),
 4624                    &worktree,
 4625                    http_client.clone(),
 4626                    fs.clone(),
 4627                    cx,
 4628                ))
 4629            }
 4630        };
 4631
 4632        let mut messages_to_report = Vec::new();
 4633        let (new_tree, to_stop) = {
 4634            let mut rebase = local.lsp_tree.rebase();
 4635            let buffers = buffer_store
 4636                .read(cx)
 4637                .buffers()
 4638                .filter_map(|buffer| {
 4639                    let raw_buffer = buffer.read(cx);
 4640                    if !local
 4641                        .registered_buffers
 4642                        .contains_key(&raw_buffer.remote_id())
 4643                    {
 4644                        return None;
 4645                    }
 4646                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4647                    let language = raw_buffer.language().cloned()?;
 4648                    Some((file, language, raw_buffer.remote_id()))
 4649                })
 4650                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4651
 4652            for (file, language, buffer_id) in buffers {
 4653                let worktree_id = file.worktree_id(cx);
 4654                let Some(worktree) = local
 4655                    .worktree_store
 4656                    .read(cx)
 4657                    .worktree_for_id(worktree_id, cx)
 4658                else {
 4659                    continue;
 4660                };
 4661
 4662                if let Some((_, apply)) = local.reuse_existing_language_server(
 4663                    rebase.server_tree(),
 4664                    &worktree,
 4665                    &language.name(),
 4666                    cx,
 4667                ) {
 4668                    (apply)(rebase.server_tree());
 4669                } else if let Some(lsp_delegate) = adapters
 4670                    .entry(worktree_id)
 4671                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4672                    .clone()
 4673                {
 4674                    let delegate =
 4675                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4676                    let path = file
 4677                        .path()
 4678                        .parent()
 4679                        .map(Arc::from)
 4680                        .unwrap_or_else(|| file.path().clone());
 4681                    let worktree_path = ProjectPath { worktree_id, path };
 4682                    let abs_path = file.abs_path(cx);
 4683                    let worktree_root = worktree.read(cx).abs_path();
 4684                    let nodes = rebase
 4685                        .walk(
 4686                            worktree_path,
 4687                            language.name(),
 4688                            language.manifest(),
 4689                            delegate.clone(),
 4690                            cx,
 4691                        )
 4692                        .collect::<Vec<_>>();
 4693
 4694                    for node in nodes {
 4695                        let server_id = node.server_id_or_init(|disposition| {
 4696                            let path = &disposition.path;
 4697                            let uri = Url::from_file_path(worktree_root.join(&path.path));
 4698                            let key = LanguageServerSeed {
 4699                                worktree_id,
 4700                                name: disposition.server_name.clone(),
 4701                                settings: disposition.settings.clone(),
 4702                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4703                                    path.worktree_id,
 4704                                    &path.path,
 4705                                    language.name(),
 4706                                ),
 4707                            };
 4708                            local.language_server_ids.remove(&key);
 4709
 4710                            let server_id = local.get_or_insert_language_server(
 4711                                &worktree,
 4712                                lsp_delegate.clone(),
 4713                                disposition,
 4714                                &language.name(),
 4715                                cx,
 4716                            );
 4717                            if let Some(state) = local.language_servers.get(&server_id)
 4718                                && let Ok(uri) = uri {
 4719                                    state.add_workspace_folder(uri);
 4720                                };
 4721                            server_id
 4722                        });
 4723
 4724                        if let Some(language_server_id) = server_id {
 4725                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4726                                language_server_id,
 4727                                name: node.name(),
 4728                                message:
 4729                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4730                                        proto::RegisteredForBuffer {
 4731                                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 4732                                            buffer_id: buffer_id.to_proto(),
 4733                                        },
 4734                                    ),
 4735                            });
 4736                        }
 4737                    }
 4738                } else {
 4739                    continue;
 4740                }
 4741            }
 4742            rebase.finish()
 4743        };
 4744        for message in messages_to_report {
 4745            cx.emit(message);
 4746        }
 4747        local.lsp_tree = new_tree;
 4748        for (id, _) in to_stop {
 4749            self.stop_local_language_server(id, cx).detach();
 4750        }
 4751    }
 4752
 4753    pub fn apply_code_action(
 4754        &self,
 4755        buffer_handle: Entity<Buffer>,
 4756        mut action: CodeAction,
 4757        push_to_history: bool,
 4758        cx: &mut Context<Self>,
 4759    ) -> Task<Result<ProjectTransaction>> {
 4760        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4761            let request = proto::ApplyCodeAction {
 4762                project_id,
 4763                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4764                action: Some(Self::serialize_code_action(&action)),
 4765            };
 4766            let buffer_store = self.buffer_store();
 4767            cx.spawn(async move |_, cx| {
 4768                let response = upstream_client
 4769                    .request(request)
 4770                    .await?
 4771                    .transaction
 4772                    .context("missing transaction")?;
 4773
 4774                buffer_store
 4775                    .update(cx, |buffer_store, cx| {
 4776                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4777                    })?
 4778                    .await
 4779            })
 4780        } else if self.mode.is_local() {
 4781            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4782                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4783                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4784            }) else {
 4785                return Task::ready(Ok(ProjectTransaction::default()));
 4786            };
 4787            cx.spawn(async move |this,  cx| {
 4788                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4789                    .await
 4790                    .context("resolving a code action")?;
 4791                if let Some(edit) = action.lsp_action.edit()
 4792                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4793                        return LocalLspStore::deserialize_workspace_edit(
 4794                            this.upgrade().context("no app present")?,
 4795                            edit.clone(),
 4796                            push_to_history,
 4797
 4798                            lang_server.clone(),
 4799                            cx,
 4800                        )
 4801                        .await;
 4802                    }
 4803
 4804                if let Some(command) = action.lsp_action.command() {
 4805                    let server_capabilities = lang_server.capabilities();
 4806                    let available_commands = server_capabilities
 4807                        .execute_command_provider
 4808                        .as_ref()
 4809                        .map(|options| options.commands.as_slice())
 4810                        .unwrap_or_default();
 4811                    if available_commands.contains(&command.command) {
 4812                        this.update(cx, |this, _| {
 4813                            this.as_local_mut()
 4814                                .unwrap()
 4815                                .last_workspace_edits_by_language_server
 4816                                .remove(&lang_server.server_id());
 4817                        })?;
 4818
 4819                        let _result = lang_server
 4820                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4821                                command: command.command.clone(),
 4822                                arguments: command.arguments.clone().unwrap_or_default(),
 4823                                ..lsp::ExecuteCommandParams::default()
 4824                            })
 4825                            .await.into_response()
 4826                            .context("execute command")?;
 4827
 4828                        return this.update(cx, |this, _| {
 4829                            this.as_local_mut()
 4830                                .unwrap()
 4831                                .last_workspace_edits_by_language_server
 4832                                .remove(&lang_server.server_id())
 4833                                .unwrap_or_default()
 4834                        });
 4835                    } else {
 4836                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4837                    }
 4838                }
 4839
 4840                Ok(ProjectTransaction::default())
 4841            })
 4842        } else {
 4843            Task::ready(Err(anyhow!("no upstream client and not local")))
 4844        }
 4845    }
 4846
 4847    pub fn apply_code_action_kind(
 4848        &mut self,
 4849        buffers: HashSet<Entity<Buffer>>,
 4850        kind: CodeActionKind,
 4851        push_to_history: bool,
 4852        cx: &mut Context<Self>,
 4853    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4854        if let Some(_) = self.as_local() {
 4855            cx.spawn(async move |lsp_store, cx| {
 4856                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4857                let result = LocalLspStore::execute_code_action_kind_locally(
 4858                    lsp_store.clone(),
 4859                    buffers,
 4860                    kind,
 4861                    push_to_history,
 4862                    cx,
 4863                )
 4864                .await;
 4865                lsp_store.update(cx, |lsp_store, _| {
 4866                    lsp_store.update_last_formatting_failure(&result);
 4867                })?;
 4868                result
 4869            })
 4870        } else if let Some((client, project_id)) = self.upstream_client() {
 4871            let buffer_store = self.buffer_store();
 4872            cx.spawn(async move |lsp_store, cx| {
 4873                let result = client
 4874                    .request(proto::ApplyCodeActionKind {
 4875                        project_id,
 4876                        kind: kind.as_str().to_owned(),
 4877                        buffer_ids: buffers
 4878                            .iter()
 4879                            .map(|buffer| {
 4880                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4881                            })
 4882                            .collect::<Result<_>>()?,
 4883                    })
 4884                    .await
 4885                    .and_then(|result| result.transaction.context("missing transaction"));
 4886                lsp_store.update(cx, |lsp_store, _| {
 4887                    lsp_store.update_last_formatting_failure(&result);
 4888                })?;
 4889
 4890                let transaction_response = result?;
 4891                buffer_store
 4892                    .update(cx, |buffer_store, cx| {
 4893                        buffer_store.deserialize_project_transaction(
 4894                            transaction_response,
 4895                            push_to_history,
 4896                            cx,
 4897                        )
 4898                    })?
 4899                    .await
 4900            })
 4901        } else {
 4902            Task::ready(Ok(ProjectTransaction::default()))
 4903        }
 4904    }
 4905
 4906    pub fn resolve_inlay_hint(
 4907        &self,
 4908        mut hint: InlayHint,
 4909        buffer: Entity<Buffer>,
 4910        server_id: LanguageServerId,
 4911        cx: &mut Context<Self>,
 4912    ) -> Task<anyhow::Result<InlayHint>> {
 4913        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4914            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4915            {
 4916                hint.resolve_state = ResolveState::Resolved;
 4917                return Task::ready(Ok(hint));
 4918            }
 4919            let request = proto::ResolveInlayHint {
 4920                project_id,
 4921                buffer_id: buffer.read(cx).remote_id().into(),
 4922                language_server_id: server_id.0 as u64,
 4923                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4924            };
 4925            cx.background_spawn(async move {
 4926                let response = upstream_client
 4927                    .request(request)
 4928                    .await
 4929                    .context("inlay hints proto request")?;
 4930                match response.hint {
 4931                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4932                        .context("inlay hints proto resolve response conversion"),
 4933                    None => Ok(hint),
 4934                }
 4935            })
 4936        } else {
 4937            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4938                self.language_server_for_local_buffer(buffer, server_id, cx)
 4939                    .map(|(_, server)| server.clone())
 4940            }) else {
 4941                return Task::ready(Ok(hint));
 4942            };
 4943            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4944                return Task::ready(Ok(hint));
 4945            }
 4946            let buffer_snapshot = buffer.read(cx).snapshot();
 4947            cx.spawn(async move |_, cx| {
 4948                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4949                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4950                );
 4951                let resolved_hint = resolve_task
 4952                    .await
 4953                    .into_response()
 4954                    .context("inlay hint resolve LSP request")?;
 4955                let resolved_hint = InlayHints::lsp_to_project_hint(
 4956                    resolved_hint,
 4957                    &buffer,
 4958                    server_id,
 4959                    ResolveState::Resolved,
 4960                    false,
 4961                    cx,
 4962                )
 4963                .await?;
 4964                Ok(resolved_hint)
 4965            })
 4966        }
 4967    }
 4968
 4969    pub fn resolve_color_presentation(
 4970        &mut self,
 4971        mut color: DocumentColor,
 4972        buffer: Entity<Buffer>,
 4973        server_id: LanguageServerId,
 4974        cx: &mut Context<Self>,
 4975    ) -> Task<Result<DocumentColor>> {
 4976        if color.resolved {
 4977            return Task::ready(Ok(color));
 4978        }
 4979
 4980        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4981            let start = color.lsp_range.start;
 4982            let end = color.lsp_range.end;
 4983            let request = proto::GetColorPresentation {
 4984                project_id,
 4985                server_id: server_id.to_proto(),
 4986                buffer_id: buffer.read(cx).remote_id().into(),
 4987                color: Some(proto::ColorInformation {
 4988                    red: color.color.red,
 4989                    green: color.color.green,
 4990                    blue: color.color.blue,
 4991                    alpha: color.color.alpha,
 4992                    lsp_range_start: Some(proto::PointUtf16 {
 4993                        row: start.line,
 4994                        column: start.character,
 4995                    }),
 4996                    lsp_range_end: Some(proto::PointUtf16 {
 4997                        row: end.line,
 4998                        column: end.character,
 4999                    }),
 5000                }),
 5001            };
 5002            cx.background_spawn(async move {
 5003                let response = upstream_client
 5004                    .request(request)
 5005                    .await
 5006                    .context("color presentation proto request")?;
 5007                color.resolved = true;
 5008                color.color_presentations = response
 5009                    .presentations
 5010                    .into_iter()
 5011                    .map(|presentation| ColorPresentation {
 5012                        label: SharedString::from(presentation.label),
 5013                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5014                        additional_text_edits: presentation
 5015                            .additional_text_edits
 5016                            .into_iter()
 5017                            .filter_map(deserialize_lsp_edit)
 5018                            .collect(),
 5019                    })
 5020                    .collect();
 5021                Ok(color)
 5022            })
 5023        } else {
 5024            let path = match buffer
 5025                .update(cx, |buffer, cx| {
 5026                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5027                })
 5028                .context("buffer with the missing path")
 5029            {
 5030                Ok(path) => path,
 5031                Err(e) => return Task::ready(Err(e)),
 5032            };
 5033            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5034                self.language_server_for_local_buffer(buffer, server_id, cx)
 5035                    .map(|(_, server)| server.clone())
 5036            }) else {
 5037                return Task::ready(Ok(color));
 5038            };
 5039            cx.background_spawn(async move {
 5040                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5041                    lsp::ColorPresentationParams {
 5042                        text_document: make_text_document_identifier(&path)?,
 5043                        color: color.color,
 5044                        range: color.lsp_range,
 5045                        work_done_progress_params: Default::default(),
 5046                        partial_result_params: Default::default(),
 5047                    },
 5048                );
 5049                color.color_presentations = resolve_task
 5050                    .await
 5051                    .into_response()
 5052                    .context("color presentation resolve LSP request")?
 5053                    .into_iter()
 5054                    .map(|presentation| ColorPresentation {
 5055                        label: SharedString::from(presentation.label),
 5056                        text_edit: presentation.text_edit,
 5057                        additional_text_edits: presentation
 5058                            .additional_text_edits
 5059                            .unwrap_or_default(),
 5060                    })
 5061                    .collect();
 5062                color.resolved = true;
 5063                Ok(color)
 5064            })
 5065        }
 5066    }
 5067
 5068    pub(crate) fn linked_edits(
 5069        &mut self,
 5070        buffer: &Entity<Buffer>,
 5071        position: Anchor,
 5072        cx: &mut Context<Self>,
 5073    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5074        let snapshot = buffer.read(cx).snapshot();
 5075        let scope = snapshot.language_scope_at(position);
 5076        let Some(server_id) = self
 5077            .as_local()
 5078            .and_then(|local| {
 5079                buffer.update(cx, |buffer, cx| {
 5080                    local
 5081                        .language_servers_for_buffer(buffer, cx)
 5082                        .filter(|(_, server)| {
 5083                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5084                        })
 5085                        .filter(|(adapter, _)| {
 5086                            scope
 5087                                .as_ref()
 5088                                .map(|scope| scope.language_allowed(&adapter.name))
 5089                                .unwrap_or(true)
 5090                        })
 5091                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5092                        .next()
 5093                })
 5094            })
 5095            .or_else(|| {
 5096                self.upstream_client()
 5097                    .is_some()
 5098                    .then_some(LanguageServerToQuery::FirstCapable)
 5099            })
 5100            .filter(|_| {
 5101                maybe!({
 5102                    let language = buffer.read(cx).language_at(position)?;
 5103                    Some(
 5104                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5105                            .linked_edits,
 5106                    )
 5107                }) == Some(true)
 5108            })
 5109        else {
 5110            return Task::ready(Ok(Vec::new()));
 5111        };
 5112
 5113        self.request_lsp(
 5114            buffer.clone(),
 5115            server_id,
 5116            LinkedEditingRange { position },
 5117            cx,
 5118        )
 5119    }
 5120
 5121    fn apply_on_type_formatting(
 5122        &mut self,
 5123        buffer: Entity<Buffer>,
 5124        position: Anchor,
 5125        trigger: String,
 5126        cx: &mut Context<Self>,
 5127    ) -> Task<Result<Option<Transaction>>> {
 5128        if let Some((client, project_id)) = self.upstream_client() {
 5129            if !self.check_if_capable_for_proto_request(
 5130                &buffer,
 5131                |capabilities| {
 5132                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5133                },
 5134                cx,
 5135            ) {
 5136                return Task::ready(Ok(None));
 5137            }
 5138            let request = proto::OnTypeFormatting {
 5139                project_id,
 5140                buffer_id: buffer.read(cx).remote_id().into(),
 5141                position: Some(serialize_anchor(&position)),
 5142                trigger,
 5143                version: serialize_version(&buffer.read(cx).version()),
 5144            };
 5145            cx.background_spawn(async move {
 5146                client
 5147                    .request(request)
 5148                    .await?
 5149                    .transaction
 5150                    .map(language::proto::deserialize_transaction)
 5151                    .transpose()
 5152            })
 5153        } else if let Some(local) = self.as_local_mut() {
 5154            let buffer_id = buffer.read(cx).remote_id();
 5155            local.buffers_being_formatted.insert(buffer_id);
 5156            cx.spawn(async move |this, cx| {
 5157                let _cleanup = defer({
 5158                    let this = this.clone();
 5159                    let mut cx = cx.clone();
 5160                    move || {
 5161                        this.update(&mut cx, |this, _| {
 5162                            if let Some(local) = this.as_local_mut() {
 5163                                local.buffers_being_formatted.remove(&buffer_id);
 5164                            }
 5165                        })
 5166                        .ok();
 5167                    }
 5168                });
 5169
 5170                buffer
 5171                    .update(cx, |buffer, _| {
 5172                        buffer.wait_for_edits(Some(position.timestamp))
 5173                    })?
 5174                    .await?;
 5175                this.update(cx, |this, cx| {
 5176                    let position = position.to_point_utf16(buffer.read(cx));
 5177                    this.on_type_format(buffer, position, trigger, false, cx)
 5178                })?
 5179                .await
 5180            })
 5181        } else {
 5182            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5183        }
 5184    }
 5185
 5186    pub fn on_type_format<T: ToPointUtf16>(
 5187        &mut self,
 5188        buffer: Entity<Buffer>,
 5189        position: T,
 5190        trigger: String,
 5191        push_to_history: bool,
 5192        cx: &mut Context<Self>,
 5193    ) -> Task<Result<Option<Transaction>>> {
 5194        let position = position.to_point_utf16(buffer.read(cx));
 5195        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5196    }
 5197
 5198    fn on_type_format_impl(
 5199        &mut self,
 5200        buffer: Entity<Buffer>,
 5201        position: PointUtf16,
 5202        trigger: String,
 5203        push_to_history: bool,
 5204        cx: &mut Context<Self>,
 5205    ) -> Task<Result<Option<Transaction>>> {
 5206        let options = buffer.update(cx, |buffer, cx| {
 5207            lsp_command::lsp_formatting_options(
 5208                language_settings(
 5209                    buffer.language_at(position).map(|l| l.name()),
 5210                    buffer.file(),
 5211                    cx,
 5212                )
 5213                .as_ref(),
 5214            )
 5215        });
 5216
 5217        cx.spawn(async move |this, cx| {
 5218            if let Some(waiter) =
 5219                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5220            {
 5221                waiter.await?;
 5222            }
 5223            cx.update(|cx| {
 5224                this.update(cx, |this, cx| {
 5225                    this.request_lsp(
 5226                        buffer.clone(),
 5227                        LanguageServerToQuery::FirstCapable,
 5228                        OnTypeFormatting {
 5229                            position,
 5230                            trigger,
 5231                            options,
 5232                            push_to_history,
 5233                        },
 5234                        cx,
 5235                    )
 5236                })
 5237            })??
 5238            .await
 5239        })
 5240    }
 5241
 5242    pub fn definitions(
 5243        &mut self,
 5244        buffer_handle: &Entity<Buffer>,
 5245        position: PointUtf16,
 5246        cx: &mut Context<Self>,
 5247    ) -> Task<Result<Vec<LocationLink>>> {
 5248        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5249            let request = GetDefinitions { position };
 5250            if !self.is_capable_for_proto_request(buffer_handle, &request, cx) {
 5251                return Task::ready(Ok(Vec::new()));
 5252            }
 5253            let request_task = upstream_client.request(proto::MultiLspQuery {
 5254                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5255                version: serialize_version(&buffer_handle.read(cx).version()),
 5256                project_id,
 5257                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5258                    proto::AllLanguageServers {},
 5259                )),
 5260                request: Some(proto::multi_lsp_query::Request::GetDefinition(
 5261                    request.to_proto(project_id, buffer_handle.read(cx)),
 5262                )),
 5263            });
 5264            let buffer = buffer_handle.clone();
 5265            cx.spawn(async move |weak_project, cx| {
 5266                let Some(project) = weak_project.upgrade() else {
 5267                    return Ok(Vec::new());
 5268                };
 5269                let responses = request_task.await?.responses;
 5270                let actions = join_all(
 5271                    responses
 5272                        .into_iter()
 5273                        .filter_map(|lsp_response| match lsp_response.response? {
 5274                            proto::lsp_response::Response::GetDefinitionResponse(response) => {
 5275                                Some(response)
 5276                            }
 5277                            unexpected => {
 5278                                debug_panic!("Unexpected response: {unexpected:?}");
 5279                                None
 5280                            }
 5281                        })
 5282                        .map(|definitions_response| {
 5283                            GetDefinitions { position }.response_from_proto(
 5284                                definitions_response,
 5285                                project.clone(),
 5286                                buffer.clone(),
 5287                                cx.clone(),
 5288                            )
 5289                        }),
 5290                )
 5291                .await;
 5292
 5293                Ok(actions
 5294                    .into_iter()
 5295                    .collect::<Result<Vec<Vec<_>>>>()?
 5296                    .into_iter()
 5297                    .flatten()
 5298                    .dedup()
 5299                    .collect())
 5300            })
 5301        } else {
 5302            let definitions_task = self.request_multiple_lsp_locally(
 5303                buffer_handle,
 5304                Some(position),
 5305                GetDefinitions { position },
 5306                cx,
 5307            );
 5308            cx.background_spawn(async move {
 5309                Ok(definitions_task
 5310                    .await
 5311                    .into_iter()
 5312                    .flat_map(|(_, definitions)| definitions)
 5313                    .dedup()
 5314                    .collect())
 5315            })
 5316        }
 5317    }
 5318
 5319    pub fn declarations(
 5320        &mut self,
 5321        buffer_handle: &Entity<Buffer>,
 5322        position: PointUtf16,
 5323        cx: &mut Context<Self>,
 5324    ) -> Task<Result<Vec<LocationLink>>> {
 5325        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5326            let request = GetDeclarations { position };
 5327            if !self.is_capable_for_proto_request(buffer_handle, &request, cx) {
 5328                return Task::ready(Ok(Vec::new()));
 5329            }
 5330            let request_task = upstream_client.request(proto::MultiLspQuery {
 5331                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5332                version: serialize_version(&buffer_handle.read(cx).version()),
 5333                project_id,
 5334                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5335                    proto::AllLanguageServers {},
 5336                )),
 5337                request: Some(proto::multi_lsp_query::Request::GetDeclaration(
 5338                    request.to_proto(project_id, buffer_handle.read(cx)),
 5339                )),
 5340            });
 5341            let buffer = buffer_handle.clone();
 5342            cx.spawn(async move |weak_project, cx| {
 5343                let Some(project) = weak_project.upgrade() else {
 5344                    return Ok(Vec::new());
 5345                };
 5346                let responses = request_task.await?.responses;
 5347                let actions = join_all(
 5348                    responses
 5349                        .into_iter()
 5350                        .filter_map(|lsp_response| match lsp_response.response? {
 5351                            proto::lsp_response::Response::GetDeclarationResponse(response) => {
 5352                                Some(response)
 5353                            }
 5354                            unexpected => {
 5355                                debug_panic!("Unexpected response: {unexpected:?}");
 5356                                None
 5357                            }
 5358                        })
 5359                        .map(|declarations_response| {
 5360                            GetDeclarations { position }.response_from_proto(
 5361                                declarations_response,
 5362                                project.clone(),
 5363                                buffer.clone(),
 5364                                cx.clone(),
 5365                            )
 5366                        }),
 5367                )
 5368                .await;
 5369
 5370                Ok(actions
 5371                    .into_iter()
 5372                    .collect::<Result<Vec<Vec<_>>>>()?
 5373                    .into_iter()
 5374                    .flatten()
 5375                    .dedup()
 5376                    .collect())
 5377            })
 5378        } else {
 5379            let declarations_task = self.request_multiple_lsp_locally(
 5380                buffer_handle,
 5381                Some(position),
 5382                GetDeclarations { position },
 5383                cx,
 5384            );
 5385            cx.background_spawn(async move {
 5386                Ok(declarations_task
 5387                    .await
 5388                    .into_iter()
 5389                    .flat_map(|(_, declarations)| declarations)
 5390                    .dedup()
 5391                    .collect())
 5392            })
 5393        }
 5394    }
 5395
 5396    pub fn type_definitions(
 5397        &mut self,
 5398        buffer: &Entity<Buffer>,
 5399        position: PointUtf16,
 5400        cx: &mut Context<Self>,
 5401    ) -> Task<Result<Vec<LocationLink>>> {
 5402        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5403            let request = GetTypeDefinitions { position };
 5404            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5405                return Task::ready(Ok(Vec::new()));
 5406            }
 5407            let request_task = upstream_client.request(proto::MultiLspQuery {
 5408                buffer_id: buffer.read(cx).remote_id().into(),
 5409                version: serialize_version(&buffer.read(cx).version()),
 5410                project_id,
 5411                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5412                    proto::AllLanguageServers {},
 5413                )),
 5414                request: Some(proto::multi_lsp_query::Request::GetTypeDefinition(
 5415                    request.to_proto(project_id, buffer.read(cx)),
 5416                )),
 5417            });
 5418            let buffer = buffer.clone();
 5419            cx.spawn(async move |weak_project, cx| {
 5420                let Some(project) = weak_project.upgrade() else {
 5421                    return Ok(Vec::new());
 5422                };
 5423                let responses = request_task.await?.responses;
 5424                let actions = join_all(
 5425                    responses
 5426                        .into_iter()
 5427                        .filter_map(|lsp_response| match lsp_response.response? {
 5428                            proto::lsp_response::Response::GetTypeDefinitionResponse(response) => {
 5429                                Some(response)
 5430                            }
 5431                            unexpected => {
 5432                                debug_panic!("Unexpected response: {unexpected:?}");
 5433                                None
 5434                            }
 5435                        })
 5436                        .map(|type_definitions_response| {
 5437                            GetTypeDefinitions { position }.response_from_proto(
 5438                                type_definitions_response,
 5439                                project.clone(),
 5440                                buffer.clone(),
 5441                                cx.clone(),
 5442                            )
 5443                        }),
 5444                )
 5445                .await;
 5446
 5447                Ok(actions
 5448                    .into_iter()
 5449                    .collect::<Result<Vec<Vec<_>>>>()?
 5450                    .into_iter()
 5451                    .flatten()
 5452                    .dedup()
 5453                    .collect())
 5454            })
 5455        } else {
 5456            let type_definitions_task = self.request_multiple_lsp_locally(
 5457                buffer,
 5458                Some(position),
 5459                GetTypeDefinitions { position },
 5460                cx,
 5461            );
 5462            cx.background_spawn(async move {
 5463                Ok(type_definitions_task
 5464                    .await
 5465                    .into_iter()
 5466                    .flat_map(|(_, type_definitions)| type_definitions)
 5467                    .dedup()
 5468                    .collect())
 5469            })
 5470        }
 5471    }
 5472
 5473    pub fn implementations(
 5474        &mut self,
 5475        buffer: &Entity<Buffer>,
 5476        position: PointUtf16,
 5477        cx: &mut Context<Self>,
 5478    ) -> Task<Result<Vec<LocationLink>>> {
 5479        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5480            let request = GetImplementations { position };
 5481            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5482                return Task::ready(Ok(Vec::new()));
 5483            }
 5484            let request_task = upstream_client.request(proto::MultiLspQuery {
 5485                buffer_id: buffer.read(cx).remote_id().into(),
 5486                version: serialize_version(&buffer.read(cx).version()),
 5487                project_id,
 5488                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5489                    proto::AllLanguageServers {},
 5490                )),
 5491                request: Some(proto::multi_lsp_query::Request::GetImplementation(
 5492                    request.to_proto(project_id, buffer.read(cx)),
 5493                )),
 5494            });
 5495            let buffer = buffer.clone();
 5496            cx.spawn(async move |weak_project, cx| {
 5497                let Some(project) = weak_project.upgrade() else {
 5498                    return Ok(Vec::new());
 5499                };
 5500                let responses = request_task.await?.responses;
 5501                let actions = join_all(
 5502                    responses
 5503                        .into_iter()
 5504                        .filter_map(|lsp_response| match lsp_response.response? {
 5505                            proto::lsp_response::Response::GetImplementationResponse(response) => {
 5506                                Some(response)
 5507                            }
 5508                            unexpected => {
 5509                                debug_panic!("Unexpected response: {unexpected:?}");
 5510                                None
 5511                            }
 5512                        })
 5513                        .map(|implementations_response| {
 5514                            GetImplementations { position }.response_from_proto(
 5515                                implementations_response,
 5516                                project.clone(),
 5517                                buffer.clone(),
 5518                                cx.clone(),
 5519                            )
 5520                        }),
 5521                )
 5522                .await;
 5523
 5524                Ok(actions
 5525                    .into_iter()
 5526                    .collect::<Result<Vec<Vec<_>>>>()?
 5527                    .into_iter()
 5528                    .flatten()
 5529                    .dedup()
 5530                    .collect())
 5531            })
 5532        } else {
 5533            let implementations_task = self.request_multiple_lsp_locally(
 5534                buffer,
 5535                Some(position),
 5536                GetImplementations { position },
 5537                cx,
 5538            );
 5539            cx.background_spawn(async move {
 5540                Ok(implementations_task
 5541                    .await
 5542                    .into_iter()
 5543                    .flat_map(|(_, implementations)| implementations)
 5544                    .dedup()
 5545                    .collect())
 5546            })
 5547        }
 5548    }
 5549
 5550    pub fn references(
 5551        &mut self,
 5552        buffer: &Entity<Buffer>,
 5553        position: PointUtf16,
 5554        cx: &mut Context<Self>,
 5555    ) -> Task<Result<Vec<Location>>> {
 5556        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5557            let request = GetReferences { position };
 5558            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5559                return Task::ready(Ok(Vec::new()));
 5560            }
 5561            let request_task = upstream_client.request(proto::MultiLspQuery {
 5562                buffer_id: buffer.read(cx).remote_id().into(),
 5563                version: serialize_version(&buffer.read(cx).version()),
 5564                project_id,
 5565                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5566                    proto::AllLanguageServers {},
 5567                )),
 5568                request: Some(proto::multi_lsp_query::Request::GetReferences(
 5569                    request.to_proto(project_id, buffer.read(cx)),
 5570                )),
 5571            });
 5572            let buffer = buffer.clone();
 5573            cx.spawn(async move |weak_project, cx| {
 5574                let Some(project) = weak_project.upgrade() else {
 5575                    return Ok(Vec::new());
 5576                };
 5577                let responses = request_task.await?.responses;
 5578                let actions = join_all(
 5579                    responses
 5580                        .into_iter()
 5581                        .filter_map(|lsp_response| match lsp_response.response? {
 5582                            proto::lsp_response::Response::GetReferencesResponse(response) => {
 5583                                Some(response)
 5584                            }
 5585                            unexpected => {
 5586                                debug_panic!("Unexpected response: {unexpected:?}");
 5587                                None
 5588                            }
 5589                        })
 5590                        .map(|references_response| {
 5591                            GetReferences { position }.response_from_proto(
 5592                                references_response,
 5593                                project.clone(),
 5594                                buffer.clone(),
 5595                                cx.clone(),
 5596                            )
 5597                        }),
 5598                )
 5599                .await;
 5600
 5601                Ok(actions
 5602                    .into_iter()
 5603                    .collect::<Result<Vec<Vec<_>>>>()?
 5604                    .into_iter()
 5605                    .flatten()
 5606                    .dedup()
 5607                    .collect())
 5608            })
 5609        } else {
 5610            let references_task = self.request_multiple_lsp_locally(
 5611                buffer,
 5612                Some(position),
 5613                GetReferences { position },
 5614                cx,
 5615            );
 5616            cx.background_spawn(async move {
 5617                Ok(references_task
 5618                    .await
 5619                    .into_iter()
 5620                    .flat_map(|(_, references)| references)
 5621                    .dedup()
 5622                    .collect())
 5623            })
 5624        }
 5625    }
 5626
 5627    pub fn code_actions(
 5628        &mut self,
 5629        buffer: &Entity<Buffer>,
 5630        range: Range<Anchor>,
 5631        kinds: Option<Vec<CodeActionKind>>,
 5632        cx: &mut Context<Self>,
 5633    ) -> Task<Result<Vec<CodeAction>>> {
 5634        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5635            let request = GetCodeActions {
 5636                range: range.clone(),
 5637                kinds: kinds.clone(),
 5638            };
 5639            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5640                return Task::ready(Ok(Vec::new()));
 5641            }
 5642            let request_task = upstream_client.request(proto::MultiLspQuery {
 5643                buffer_id: buffer.read(cx).remote_id().into(),
 5644                version: serialize_version(&buffer.read(cx).version()),
 5645                project_id,
 5646                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5647                    proto::AllLanguageServers {},
 5648                )),
 5649                request: Some(proto::multi_lsp_query::Request::GetCodeActions(
 5650                    request.to_proto(project_id, buffer.read(cx)),
 5651                )),
 5652            });
 5653            let buffer = buffer.clone();
 5654            cx.spawn(async move |weak_project, cx| {
 5655                let Some(project) = weak_project.upgrade() else {
 5656                    return Ok(Vec::new());
 5657                };
 5658                let responses = request_task.await?.responses;
 5659                let actions = join_all(
 5660                    responses
 5661                        .into_iter()
 5662                        .filter_map(|lsp_response| match lsp_response.response? {
 5663                            proto::lsp_response::Response::GetCodeActionsResponse(response) => {
 5664                                Some(response)
 5665                            }
 5666                            unexpected => {
 5667                                debug_panic!("Unexpected response: {unexpected:?}");
 5668                                None
 5669                            }
 5670                        })
 5671                        .map(|code_actions_response| {
 5672                            GetCodeActions {
 5673                                range: range.clone(),
 5674                                kinds: kinds.clone(),
 5675                            }
 5676                            .response_from_proto(
 5677                                code_actions_response,
 5678                                project.clone(),
 5679                                buffer.clone(),
 5680                                cx.clone(),
 5681                            )
 5682                        }),
 5683                )
 5684                .await;
 5685
 5686                Ok(actions
 5687                    .into_iter()
 5688                    .collect::<Result<Vec<Vec<_>>>>()?
 5689                    .into_iter()
 5690                    .flatten()
 5691                    .collect())
 5692            })
 5693        } else {
 5694            let all_actions_task = self.request_multiple_lsp_locally(
 5695                buffer,
 5696                Some(range.start),
 5697                GetCodeActions {
 5698                    range: range.clone(),
 5699                    kinds: kinds.clone(),
 5700                },
 5701                cx,
 5702            );
 5703            cx.background_spawn(async move {
 5704                Ok(all_actions_task
 5705                    .await
 5706                    .into_iter()
 5707                    .flat_map(|(_, actions)| actions)
 5708                    .collect())
 5709            })
 5710        }
 5711    }
 5712
 5713    pub fn code_lens_actions(
 5714        &mut self,
 5715        buffer: &Entity<Buffer>,
 5716        cx: &mut Context<Self>,
 5717    ) -> CodeLensTask {
 5718        let version_queried_for = buffer.read(cx).version();
 5719        let buffer_id = buffer.read(cx).remote_id();
 5720
 5721        if let Some(cached_data) = self.lsp_code_lens.get(&buffer_id)
 5722            && !version_queried_for.changed_since(&cached_data.lens_for_version) {
 5723                let has_different_servers = self.as_local().is_some_and(|local| {
 5724                    local
 5725                        .buffers_opened_in_servers
 5726                        .get(&buffer_id)
 5727                        .cloned()
 5728                        .unwrap_or_default()
 5729                        != cached_data.lens.keys().copied().collect()
 5730                });
 5731                if !has_different_servers {
 5732                    return Task::ready(Ok(cached_data.lens.values().flatten().cloned().collect()))
 5733                        .shared();
 5734                }
 5735            }
 5736
 5737        let lsp_data = self.lsp_code_lens.entry(buffer_id).or_default();
 5738        if let Some((updating_for, running_update)) = &lsp_data.update
 5739            && !version_queried_for.changed_since(updating_for) {
 5740                return running_update.clone();
 5741            }
 5742        let buffer = buffer.clone();
 5743        let query_version_queried_for = version_queried_for.clone();
 5744        let new_task = cx
 5745            .spawn(async move |lsp_store, cx| {
 5746                cx.background_executor()
 5747                    .timer(Duration::from_millis(30))
 5748                    .await;
 5749                let fetched_lens = lsp_store
 5750                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5751                    .map_err(Arc::new)?
 5752                    .await
 5753                    .context("fetching code lens")
 5754                    .map_err(Arc::new);
 5755                let fetched_lens = match fetched_lens {
 5756                    Ok(fetched_lens) => fetched_lens,
 5757                    Err(e) => {
 5758                        lsp_store
 5759                            .update(cx, |lsp_store, _| {
 5760                                lsp_store.lsp_code_lens.entry(buffer_id).or_default().update = None;
 5761                            })
 5762                            .ok();
 5763                        return Err(e);
 5764                    }
 5765                };
 5766
 5767                lsp_store
 5768                    .update(cx, |lsp_store, _| {
 5769                        let lsp_data = lsp_store.lsp_code_lens.entry(buffer_id).or_default();
 5770                        if lsp_data.lens_for_version == query_version_queried_for {
 5771                            lsp_data.lens.extend(fetched_lens.clone());
 5772                        } else if !lsp_data
 5773                            .lens_for_version
 5774                            .changed_since(&query_version_queried_for)
 5775                        {
 5776                            lsp_data.lens_for_version = query_version_queried_for;
 5777                            lsp_data.lens = fetched_lens.clone();
 5778                        }
 5779                        lsp_data.update = None;
 5780                        lsp_data.lens.values().flatten().cloned().collect()
 5781                    })
 5782                    .map_err(Arc::new)
 5783            })
 5784            .shared();
 5785        lsp_data.update = Some((version_queried_for, new_task.clone()));
 5786        new_task
 5787    }
 5788
 5789    fn fetch_code_lens(
 5790        &mut self,
 5791        buffer: &Entity<Buffer>,
 5792        cx: &mut Context<Self>,
 5793    ) -> Task<Result<HashMap<LanguageServerId, Vec<CodeAction>>>> {
 5794        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5795            let request = GetCodeLens;
 5796            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5797                return Task::ready(Ok(HashMap::default()));
 5798            }
 5799            let request_task = upstream_client.request(proto::MultiLspQuery {
 5800                buffer_id: buffer.read(cx).remote_id().into(),
 5801                version: serialize_version(&buffer.read(cx).version()),
 5802                project_id,
 5803                strategy: Some(proto::multi_lsp_query::Strategy::All(
 5804                    proto::AllLanguageServers {},
 5805                )),
 5806                request: Some(proto::multi_lsp_query::Request::GetCodeLens(
 5807                    request.to_proto(project_id, buffer.read(cx)),
 5808                )),
 5809            });
 5810            let buffer = buffer.clone();
 5811            cx.spawn(async move |weak_lsp_store, cx| {
 5812                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5813                    return Ok(HashMap::default());
 5814                };
 5815                let responses = request_task.await?.responses;
 5816                let code_lens_actions = join_all(
 5817                    responses
 5818                        .into_iter()
 5819                        .filter_map(|lsp_response| {
 5820                            let response = match lsp_response.response? {
 5821                                proto::lsp_response::Response::GetCodeLensResponse(response) => {
 5822                                    Some(response)
 5823                                }
 5824                                unexpected => {
 5825                                    debug_panic!("Unexpected response: {unexpected:?}");
 5826                                    None
 5827                                }
 5828                            }?;
 5829                            let server_id = LanguageServerId::from_proto(lsp_response.server_id);
 5830                            Some((server_id, response))
 5831                        })
 5832                        .map(|(server_id, code_lens_response)| {
 5833                            let lsp_store = lsp_store.clone();
 5834                            let buffer = buffer.clone();
 5835                            let cx = cx.clone();
 5836                            async move {
 5837                                (
 5838                                    server_id,
 5839                                    GetCodeLens
 5840                                        .response_from_proto(
 5841                                            code_lens_response,
 5842                                            lsp_store,
 5843                                            buffer,
 5844                                            cx,
 5845                                        )
 5846                                        .await,
 5847                                )
 5848                            }
 5849                        }),
 5850                )
 5851                .await;
 5852
 5853                let mut has_errors = false;
 5854                let code_lens_actions = code_lens_actions
 5855                    .into_iter()
 5856                    .filter_map(|(server_id, code_lens)| match code_lens {
 5857                        Ok(code_lens) => Some((server_id, code_lens)),
 5858                        Err(e) => {
 5859                            has_errors = true;
 5860                            log::error!("{e:#}");
 5861                            None
 5862                        }
 5863                    })
 5864                    .collect::<HashMap<_, _>>();
 5865                anyhow::ensure!(
 5866                    !has_errors || !code_lens_actions.is_empty(),
 5867                    "Failed to fetch code lens"
 5868                );
 5869                Ok(code_lens_actions)
 5870            })
 5871        } else {
 5872            let code_lens_actions_task =
 5873                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5874            cx.background_spawn(
 5875                async move { Ok(code_lens_actions_task.await.into_iter().collect()) },
 5876            )
 5877        }
 5878    }
 5879
 5880    #[inline(never)]
 5881    pub fn completions(
 5882        &self,
 5883        buffer: &Entity<Buffer>,
 5884        position: PointUtf16,
 5885        context: CompletionContext,
 5886        cx: &mut Context<Self>,
 5887    ) -> Task<Result<Vec<CompletionResponse>>> {
 5888        let language_registry = self.languages.clone();
 5889
 5890        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5891            let request = GetCompletions { position, context };
 5892            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5893                return Task::ready(Ok(Vec::new()));
 5894            }
 5895            let task = self.send_lsp_proto_request(
 5896                buffer.clone(),
 5897                upstream_client,
 5898                project_id,
 5899                request,
 5900                cx,
 5901            );
 5902            let language = buffer.read(cx).language().cloned();
 5903
 5904            // In the future, we should provide project guests with the names of LSP adapters,
 5905            // so that they can use the correct LSP adapter when computing labels. For now,
 5906            // guests just use the first LSP adapter associated with the buffer's language.
 5907            let lsp_adapter = language.as_ref().and_then(|language| {
 5908                language_registry
 5909                    .lsp_adapters(&language.name())
 5910                    .first()
 5911                    .cloned()
 5912            });
 5913
 5914            cx.foreground_executor().spawn(async move {
 5915                let completion_response = task.await?;
 5916                let completions = populate_labels_for_completions(
 5917                    completion_response.completions,
 5918                    language,
 5919                    lsp_adapter,
 5920                )
 5921                .await;
 5922                Ok(vec![CompletionResponse {
 5923                    completions,
 5924                    is_incomplete: completion_response.is_incomplete,
 5925                }])
 5926            })
 5927        } else if let Some(local) = self.as_local() {
 5928            let snapshot = buffer.read(cx).snapshot();
 5929            let offset = position.to_offset(&snapshot);
 5930            let scope = snapshot.language_scope_at(offset);
 5931            let language = snapshot.language().cloned();
 5932            let completion_settings = language_settings(
 5933                language.as_ref().map(|language| language.name()),
 5934                buffer.read(cx).file(),
 5935                cx,
 5936            )
 5937            .completions;
 5938            if !completion_settings.lsp {
 5939                return Task::ready(Ok(Vec::new()));
 5940            }
 5941
 5942            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5943                local
 5944                    .language_servers_for_buffer(buffer, cx)
 5945                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5946                    .filter(|(adapter, _)| {
 5947                        scope
 5948                            .as_ref()
 5949                            .map(|scope| scope.language_allowed(&adapter.name))
 5950                            .unwrap_or(true)
 5951                    })
 5952                    .map(|(_, server)| server.server_id())
 5953                    .collect()
 5954            });
 5955
 5956            let buffer = buffer.clone();
 5957            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5958            let lsp_timeout = if lsp_timeout > 0 {
 5959                Some(Duration::from_millis(lsp_timeout))
 5960            } else {
 5961                None
 5962            };
 5963            cx.spawn(async move |this,  cx| {
 5964                let mut tasks = Vec::with_capacity(server_ids.len());
 5965                this.update(cx, |lsp_store, cx| {
 5966                    for server_id in server_ids {
 5967                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5968                        let lsp_timeout = lsp_timeout
 5969                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5970                        let mut timeout = cx.background_spawn(async move {
 5971                            match lsp_timeout {
 5972                                Some(lsp_timeout) => {
 5973                                    lsp_timeout.await;
 5974                                    true
 5975                                },
 5976                                None => false,
 5977                            }
 5978                        }).fuse();
 5979                        let mut lsp_request = lsp_store.request_lsp(
 5980                            buffer.clone(),
 5981                            LanguageServerToQuery::Other(server_id),
 5982                            GetCompletions {
 5983                                position,
 5984                                context: context.clone(),
 5985                            },
 5986                            cx,
 5987                        ).fuse();
 5988                        let new_task = cx.background_spawn(async move {
 5989                            select_biased! {
 5990                                response = lsp_request => anyhow::Ok(Some(response?)),
 5991                                timeout_happened = timeout => {
 5992                                    if timeout_happened {
 5993                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5994                                        Ok(None)
 5995                                    } else {
 5996                                        let completions = lsp_request.await?;
 5997                                        Ok(Some(completions))
 5998                                    }
 5999                                },
 6000                            }
 6001                        });
 6002                        tasks.push((lsp_adapter, new_task));
 6003                    }
 6004                })?;
 6005
 6006                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6007                    let completion_response = task.await.ok()??;
 6008                    let completions = populate_labels_for_completions(
 6009                            completion_response.completions,
 6010                            language.clone(),
 6011                            lsp_adapter,
 6012                        )
 6013                        .await;
 6014                    Some(CompletionResponse {
 6015                        completions,
 6016                        is_incomplete: completion_response.is_incomplete,
 6017                    })
 6018                });
 6019
 6020                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6021
 6022                Ok(responses.into_iter().flatten().collect())
 6023            })
 6024        } else {
 6025            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6026        }
 6027    }
 6028
 6029    pub fn resolve_completions(
 6030        &self,
 6031        buffer: Entity<Buffer>,
 6032        completion_indices: Vec<usize>,
 6033        completions: Rc<RefCell<Box<[Completion]>>>,
 6034        cx: &mut Context<Self>,
 6035    ) -> Task<Result<bool>> {
 6036        let client = self.upstream_client();
 6037        let buffer_id = buffer.read(cx).remote_id();
 6038        let buffer_snapshot = buffer.read(cx).snapshot();
 6039
 6040        if !self.check_if_capable_for_proto_request(
 6041            &buffer,
 6042            GetCompletions::can_resolve_completions,
 6043            cx,
 6044        ) {
 6045            return Task::ready(Ok(false));
 6046        }
 6047        cx.spawn(async move |lsp_store, cx| {
 6048            let mut did_resolve = false;
 6049            if let Some((client, project_id)) = client {
 6050                for completion_index in completion_indices {
 6051                    let server_id = {
 6052                        let completion = &completions.borrow()[completion_index];
 6053                        completion.source.server_id()
 6054                    };
 6055                    if let Some(server_id) = server_id {
 6056                        if Self::resolve_completion_remote(
 6057                            project_id,
 6058                            server_id,
 6059                            buffer_id,
 6060                            completions.clone(),
 6061                            completion_index,
 6062                            client.clone(),
 6063                        )
 6064                        .await
 6065                        .log_err()
 6066                        .is_some()
 6067                        {
 6068                            did_resolve = true;
 6069                        }
 6070                    } else {
 6071                        resolve_word_completion(
 6072                            &buffer_snapshot,
 6073                            &mut completions.borrow_mut()[completion_index],
 6074                        );
 6075                    }
 6076                }
 6077            } else {
 6078                for completion_index in completion_indices {
 6079                    let server_id = {
 6080                        let completion = &completions.borrow()[completion_index];
 6081                        completion.source.server_id()
 6082                    };
 6083                    if let Some(server_id) = server_id {
 6084                        let server_and_adapter = lsp_store
 6085                            .read_with(cx, |lsp_store, _| {
 6086                                let server = lsp_store.language_server_for_id(server_id)?;
 6087                                let adapter =
 6088                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6089                                Some((server, adapter))
 6090                            })
 6091                            .ok()
 6092                            .flatten();
 6093                        let Some((server, adapter)) = server_and_adapter else {
 6094                            continue;
 6095                        };
 6096
 6097                        let resolved = Self::resolve_completion_local(
 6098                            server,
 6099                            completions.clone(),
 6100                            completion_index,
 6101                        )
 6102                        .await
 6103                        .log_err()
 6104                        .is_some();
 6105                        if resolved {
 6106                            Self::regenerate_completion_labels(
 6107                                adapter,
 6108                                &buffer_snapshot,
 6109                                completions.clone(),
 6110                                completion_index,
 6111                            )
 6112                            .await
 6113                            .log_err();
 6114                            did_resolve = true;
 6115                        }
 6116                    } else {
 6117                        resolve_word_completion(
 6118                            &buffer_snapshot,
 6119                            &mut completions.borrow_mut()[completion_index],
 6120                        );
 6121                    }
 6122                }
 6123            }
 6124
 6125            Ok(did_resolve)
 6126        })
 6127    }
 6128
 6129    async fn resolve_completion_local(
 6130        server: Arc<lsp::LanguageServer>,
 6131        completions: Rc<RefCell<Box<[Completion]>>>,
 6132        completion_index: usize,
 6133    ) -> Result<()> {
 6134        let server_id = server.server_id();
 6135        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6136            return Ok(());
 6137        }
 6138
 6139        let request = {
 6140            let completion = &completions.borrow()[completion_index];
 6141            match &completion.source {
 6142                CompletionSource::Lsp {
 6143                    lsp_completion,
 6144                    resolved,
 6145                    server_id: completion_server_id,
 6146                    ..
 6147                } => {
 6148                    if *resolved {
 6149                        return Ok(());
 6150                    }
 6151                    anyhow::ensure!(
 6152                        server_id == *completion_server_id,
 6153                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6154                    );
 6155                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6156                }
 6157                CompletionSource::BufferWord { .. }
 6158                | CompletionSource::Dap { .. }
 6159                | CompletionSource::Custom => {
 6160                    return Ok(());
 6161                }
 6162            }
 6163        };
 6164        let resolved_completion = request
 6165            .await
 6166            .into_response()
 6167            .context("resolve completion")?;
 6168
 6169        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6170        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6171
 6172        let mut completions = completions.borrow_mut();
 6173        let completion = &mut completions[completion_index];
 6174        if let CompletionSource::Lsp {
 6175            lsp_completion,
 6176            resolved,
 6177            server_id: completion_server_id,
 6178            ..
 6179        } = &mut completion.source
 6180        {
 6181            if *resolved {
 6182                return Ok(());
 6183            }
 6184            anyhow::ensure!(
 6185                server_id == *completion_server_id,
 6186                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6187            );
 6188            *lsp_completion = Box::new(resolved_completion);
 6189            *resolved = true;
 6190        }
 6191        Ok(())
 6192    }
 6193
 6194    async fn regenerate_completion_labels(
 6195        adapter: Arc<CachedLspAdapter>,
 6196        snapshot: &BufferSnapshot,
 6197        completions: Rc<RefCell<Box<[Completion]>>>,
 6198        completion_index: usize,
 6199    ) -> Result<()> {
 6200        let completion_item = completions.borrow()[completion_index]
 6201            .source
 6202            .lsp_completion(true)
 6203            .map(Cow::into_owned);
 6204        if let Some(lsp_documentation) = completion_item
 6205            .as_ref()
 6206            .and_then(|completion_item| completion_item.documentation.clone())
 6207        {
 6208            let mut completions = completions.borrow_mut();
 6209            let completion = &mut completions[completion_index];
 6210            completion.documentation = Some(lsp_documentation.into());
 6211        } else {
 6212            let mut completions = completions.borrow_mut();
 6213            let completion = &mut completions[completion_index];
 6214            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6215        }
 6216
 6217        let mut new_label = match completion_item {
 6218            Some(completion_item) => {
 6219                // 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
 6220                // So we have to update the label here anyway...
 6221                let language = snapshot.language();
 6222                match language {
 6223                    Some(language) => {
 6224                        adapter
 6225                            .labels_for_completions(
 6226                                std::slice::from_ref(&completion_item),
 6227                                language,
 6228                            )
 6229                            .await?
 6230                    }
 6231                    None => Vec::new(),
 6232                }
 6233                .pop()
 6234                .flatten()
 6235                .unwrap_or_else(|| {
 6236                    CodeLabel::fallback_for_completion(
 6237                        &completion_item,
 6238                        language.map(|language| language.as_ref()),
 6239                    )
 6240                })
 6241            }
 6242            None => CodeLabel::plain(
 6243                completions.borrow()[completion_index].new_text.clone(),
 6244                None,
 6245            ),
 6246        };
 6247        ensure_uniform_list_compatible_label(&mut new_label);
 6248
 6249        let mut completions = completions.borrow_mut();
 6250        let completion = &mut completions[completion_index];
 6251        if completion.label.filter_text() == new_label.filter_text() {
 6252            completion.label = new_label;
 6253        } else {
 6254            log::error!(
 6255                "Resolved completion changed display label from {} to {}. \
 6256                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6257                completion.label.text(),
 6258                new_label.text(),
 6259                completion.label.filter_text(),
 6260                new_label.filter_text()
 6261            );
 6262        }
 6263
 6264        Ok(())
 6265    }
 6266
 6267    async fn resolve_completion_remote(
 6268        project_id: u64,
 6269        server_id: LanguageServerId,
 6270        buffer_id: BufferId,
 6271        completions: Rc<RefCell<Box<[Completion]>>>,
 6272        completion_index: usize,
 6273        client: AnyProtoClient,
 6274    ) -> Result<()> {
 6275        let lsp_completion = {
 6276            let completion = &completions.borrow()[completion_index];
 6277            match &completion.source {
 6278                CompletionSource::Lsp {
 6279                    lsp_completion,
 6280                    resolved,
 6281                    server_id: completion_server_id,
 6282                    ..
 6283                } => {
 6284                    anyhow::ensure!(
 6285                        server_id == *completion_server_id,
 6286                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6287                    );
 6288                    if *resolved {
 6289                        return Ok(());
 6290                    }
 6291                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6292                }
 6293                CompletionSource::Custom
 6294                | CompletionSource::Dap { .. }
 6295                | CompletionSource::BufferWord { .. } => {
 6296                    return Ok(());
 6297                }
 6298            }
 6299        };
 6300        let request = proto::ResolveCompletionDocumentation {
 6301            project_id,
 6302            language_server_id: server_id.0 as u64,
 6303            lsp_completion,
 6304            buffer_id: buffer_id.into(),
 6305        };
 6306
 6307        let response = client
 6308            .request(request)
 6309            .await
 6310            .context("completion documentation resolve proto request")?;
 6311        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6312
 6313        let documentation = if response.documentation.is_empty() {
 6314            CompletionDocumentation::Undocumented
 6315        } else if response.documentation_is_markdown {
 6316            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6317        } else if response.documentation.lines().count() <= 1 {
 6318            CompletionDocumentation::SingleLine(response.documentation.into())
 6319        } else {
 6320            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6321        };
 6322
 6323        let mut completions = completions.borrow_mut();
 6324        let completion = &mut completions[completion_index];
 6325        completion.documentation = Some(documentation);
 6326        if let CompletionSource::Lsp {
 6327            insert_range,
 6328            lsp_completion,
 6329            resolved,
 6330            server_id: completion_server_id,
 6331            lsp_defaults: _,
 6332        } = &mut completion.source
 6333        {
 6334            let completion_insert_range = response
 6335                .old_insert_start
 6336                .and_then(deserialize_anchor)
 6337                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6338            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6339
 6340            if *resolved {
 6341                return Ok(());
 6342            }
 6343            anyhow::ensure!(
 6344                server_id == *completion_server_id,
 6345                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6346            );
 6347            *lsp_completion = Box::new(resolved_lsp_completion);
 6348            *resolved = true;
 6349        }
 6350
 6351        let replace_range = response
 6352            .old_replace_start
 6353            .and_then(deserialize_anchor)
 6354            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6355        if let Some((old_replace_start, old_replace_end)) = replace_range
 6356            && !response.new_text.is_empty() {
 6357                completion.new_text = response.new_text;
 6358                completion.replace_range = old_replace_start..old_replace_end;
 6359            }
 6360
 6361        Ok(())
 6362    }
 6363
 6364    pub fn apply_additional_edits_for_completion(
 6365        &self,
 6366        buffer_handle: Entity<Buffer>,
 6367        completions: Rc<RefCell<Box<[Completion]>>>,
 6368        completion_index: usize,
 6369        push_to_history: bool,
 6370        cx: &mut Context<Self>,
 6371    ) -> Task<Result<Option<Transaction>>> {
 6372        if let Some((client, project_id)) = self.upstream_client() {
 6373            let buffer = buffer_handle.read(cx);
 6374            let buffer_id = buffer.remote_id();
 6375            cx.spawn(async move |_, cx| {
 6376                let request = {
 6377                    let completion = completions.borrow()[completion_index].clone();
 6378                    proto::ApplyCompletionAdditionalEdits {
 6379                        project_id,
 6380                        buffer_id: buffer_id.into(),
 6381                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6382                            replace_range: completion.replace_range,
 6383                            new_text: completion.new_text,
 6384                            source: completion.source,
 6385                        })),
 6386                    }
 6387                };
 6388
 6389                if let Some(transaction) = client.request(request).await?.transaction {
 6390                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6391                    buffer_handle
 6392                        .update(cx, |buffer, _| {
 6393                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6394                        })?
 6395                        .await?;
 6396                    if push_to_history {
 6397                        buffer_handle.update(cx, |buffer, _| {
 6398                            buffer.push_transaction(transaction.clone(), Instant::now());
 6399                            buffer.finalize_last_transaction();
 6400                        })?;
 6401                    }
 6402                    Ok(Some(transaction))
 6403                } else {
 6404                    Ok(None)
 6405                }
 6406            })
 6407        } else {
 6408            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6409                let completion = &completions.borrow()[completion_index];
 6410                let server_id = completion.source.server_id()?;
 6411                Some(
 6412                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6413                        .1
 6414                        .clone(),
 6415                )
 6416            }) else {
 6417                return Task::ready(Ok(None));
 6418            };
 6419
 6420            cx.spawn(async move |this, cx| {
 6421                Self::resolve_completion_local(
 6422                    server.clone(),
 6423                    completions.clone(),
 6424                    completion_index,
 6425                )
 6426                .await
 6427                .context("resolving completion")?;
 6428                let completion = completions.borrow()[completion_index].clone();
 6429                let additional_text_edits = completion
 6430                    .source
 6431                    .lsp_completion(true)
 6432                    .as_ref()
 6433                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6434                if let Some(edits) = additional_text_edits {
 6435                    let edits = this
 6436                        .update(cx, |this, cx| {
 6437                            this.as_local_mut().unwrap().edits_from_lsp(
 6438                                &buffer_handle,
 6439                                edits,
 6440                                server.server_id(),
 6441                                None,
 6442                                cx,
 6443                            )
 6444                        })?
 6445                        .await?;
 6446
 6447                    buffer_handle.update(cx, |buffer, cx| {
 6448                        buffer.finalize_last_transaction();
 6449                        buffer.start_transaction();
 6450
 6451                        for (range, text) in edits {
 6452                            let primary = &completion.replace_range;
 6453                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6454                                && primary.end.cmp(&range.start, buffer).is_ge();
 6455                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6456                                && range.end.cmp(&primary.end, buffer).is_ge();
 6457
 6458                            //Skip additional edits which overlap with the primary completion edit
 6459                            //https://github.com/zed-industries/zed/pull/1871
 6460                            if !start_within && !end_within {
 6461                                buffer.edit([(range, text)], None, cx);
 6462                            }
 6463                        }
 6464
 6465                        let transaction = if buffer.end_transaction(cx).is_some() {
 6466                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6467                            if !push_to_history {
 6468                                buffer.forget_transaction(transaction.id);
 6469                            }
 6470                            Some(transaction)
 6471                        } else {
 6472                            None
 6473                        };
 6474                        Ok(transaction)
 6475                    })?
 6476                } else {
 6477                    Ok(None)
 6478                }
 6479            })
 6480        }
 6481    }
 6482
 6483    pub fn pull_diagnostics(
 6484        &mut self,
 6485        buffer: Entity<Buffer>,
 6486        cx: &mut Context<Self>,
 6487    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6488        let buffer_id = buffer.read(cx).remote_id();
 6489
 6490        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6491            if !self.is_capable_for_proto_request(
 6492                &buffer,
 6493                &GetDocumentDiagnostics {
 6494                    previous_result_id: None,
 6495                },
 6496                cx,
 6497            ) {
 6498                return Task::ready(Ok(None));
 6499            }
 6500            let request_task = client.request(proto::MultiLspQuery {
 6501                buffer_id: buffer_id.to_proto(),
 6502                version: serialize_version(&buffer.read(cx).version()),
 6503                project_id: upstream_project_id,
 6504                strategy: Some(proto::multi_lsp_query::Strategy::All(
 6505                    proto::AllLanguageServers {},
 6506                )),
 6507                request: Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(
 6508                    proto::GetDocumentDiagnostics {
 6509                        project_id: upstream_project_id,
 6510                        buffer_id: buffer_id.to_proto(),
 6511                        version: serialize_version(&buffer.read(cx).version()),
 6512                    },
 6513                )),
 6514            });
 6515            cx.background_spawn(async move {
 6516                let _proto_responses = request_task
 6517                    .await?
 6518                    .responses
 6519                    .into_iter()
 6520                    .filter_map(|lsp_response| match lsp_response.response? {
 6521                        proto::lsp_response::Response::GetDocumentDiagnosticsResponse(response) => {
 6522                            Some(response)
 6523                        }
 6524                        unexpected => {
 6525                            debug_panic!("Unexpected response: {unexpected:?}");
 6526                            None
 6527                        }
 6528                    })
 6529                    .collect::<Vec<_>>();
 6530                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6531                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6532                // Do not attempt to further process the dummy responses here.
 6533                Ok(None)
 6534            })
 6535        } else {
 6536            let server_ids = buffer.update(cx, |buffer, cx| {
 6537                self.language_servers_for_local_buffer(buffer, cx)
 6538                    .map(|(_, server)| server.server_id())
 6539                    .collect::<Vec<_>>()
 6540            });
 6541            let pull_diagnostics = server_ids
 6542                .into_iter()
 6543                .map(|server_id| {
 6544                    let result_id = self.result_id(server_id, buffer_id, cx);
 6545                    self.request_lsp(
 6546                        buffer.clone(),
 6547                        LanguageServerToQuery::Other(server_id),
 6548                        GetDocumentDiagnostics {
 6549                            previous_result_id: result_id,
 6550                        },
 6551                        cx,
 6552                    )
 6553                })
 6554                .collect::<Vec<_>>();
 6555
 6556            cx.background_spawn(async move {
 6557                let mut responses = Vec::new();
 6558                for diagnostics in join_all(pull_diagnostics).await {
 6559                    responses.extend(diagnostics?);
 6560                }
 6561                Ok(Some(responses))
 6562            })
 6563        }
 6564    }
 6565
 6566    pub fn inlay_hints(
 6567        &mut self,
 6568        buffer: Entity<Buffer>,
 6569        range: Range<Anchor>,
 6570        cx: &mut Context<Self>,
 6571    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6572        let range_start = range.start;
 6573        let range_end = range.end;
 6574        let buffer_id = buffer.read(cx).remote_id().into();
 6575        let request = InlayHints { range };
 6576
 6577        if let Some((client, project_id)) = self.upstream_client() {
 6578            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6579                return Task::ready(Ok(Vec::new()));
 6580            }
 6581            let proto_request = proto::InlayHints {
 6582                project_id,
 6583                buffer_id,
 6584                start: Some(serialize_anchor(&range_start)),
 6585                end: Some(serialize_anchor(&range_end)),
 6586                version: serialize_version(&buffer.read(cx).version()),
 6587            };
 6588            cx.spawn(async move |project, cx| {
 6589                let response = client
 6590                    .request(proto_request)
 6591                    .await
 6592                    .context("inlay hints proto request")?;
 6593                LspCommand::response_from_proto(
 6594                    request,
 6595                    response,
 6596                    project.upgrade().context("No project")?,
 6597                    buffer.clone(),
 6598                    cx.clone(),
 6599                )
 6600                .await
 6601                .context("inlay hints proto response conversion")
 6602            })
 6603        } else {
 6604            let lsp_request_task = self.request_lsp(
 6605                buffer.clone(),
 6606                LanguageServerToQuery::FirstCapable,
 6607                request,
 6608                cx,
 6609            );
 6610            cx.spawn(async move |_, cx| {
 6611                buffer
 6612                    .update(cx, |buffer, _| {
 6613                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6614                    })?
 6615                    .await
 6616                    .context("waiting for inlay hint request range edits")?;
 6617                lsp_request_task.await.context("inlay hints LSP request")
 6618            })
 6619        }
 6620    }
 6621
 6622    pub fn pull_diagnostics_for_buffer(
 6623        &mut self,
 6624        buffer: Entity<Buffer>,
 6625        cx: &mut Context<Self>,
 6626    ) -> Task<anyhow::Result<()>> {
 6627        let diagnostics = self.pull_diagnostics(buffer, cx);
 6628        cx.spawn(async move |lsp_store, cx| {
 6629            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6630                return Ok(());
 6631            };
 6632            lsp_store.update(cx, |lsp_store, cx| {
 6633                if lsp_store.as_local().is_none() {
 6634                    return;
 6635                }
 6636
 6637                let mut unchanged_buffers = HashSet::default();
 6638                let mut changed_buffers = HashSet::default();
 6639                let server_diagnostics_updates = diagnostics
 6640                    .into_iter()
 6641                    .filter_map(|diagnostics_set| match diagnostics_set {
 6642                        LspPullDiagnostics::Response {
 6643                            server_id,
 6644                            uri,
 6645                            diagnostics,
 6646                        } => Some((server_id, uri, diagnostics)),
 6647                        LspPullDiagnostics::Default => None,
 6648                    })
 6649                    .fold(
 6650                        HashMap::default(),
 6651                        |mut acc, (server_id, uri, diagnostics)| {
 6652                            let (result_id, diagnostics) = match diagnostics {
 6653                                PulledDiagnostics::Unchanged { result_id } => {
 6654                                    unchanged_buffers.insert(uri.clone());
 6655                                    (Some(result_id), Vec::new())
 6656                                }
 6657                                PulledDiagnostics::Changed {
 6658                                    result_id,
 6659                                    diagnostics,
 6660                                } => {
 6661                                    changed_buffers.insert(uri.clone());
 6662                                    (result_id, diagnostics)
 6663                                }
 6664                            };
 6665                            let disk_based_sources = Cow::Owned(
 6666                                lsp_store
 6667                                    .language_server_adapter_for_id(server_id)
 6668                                    .as_ref()
 6669                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6670                                    .unwrap_or(&[])
 6671                                    .to_vec(),
 6672                            );
 6673                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6674                                DocumentDiagnosticsUpdate {
 6675                                    server_id,
 6676                                    diagnostics: lsp::PublishDiagnosticsParams {
 6677                                        uri,
 6678                                        diagnostics,
 6679                                        version: None,
 6680                                    },
 6681                                    result_id,
 6682                                    disk_based_sources,
 6683                                },
 6684                            );
 6685                            acc
 6686                        },
 6687                    );
 6688
 6689                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6690                    lsp_store
 6691                        .merge_lsp_diagnostics(
 6692                            DiagnosticSourceKind::Pulled,
 6693                            diagnostic_updates,
 6694                            |buffer, old_diagnostic, cx| {
 6695                                File::from_dyn(buffer.file())
 6696                                    .and_then(|file| {
 6697                                        let abs_path = file.as_local()?.abs_path(cx);
 6698                                        lsp::Url::from_file_path(abs_path).ok()
 6699                                    })
 6700                                    .is_none_or(|buffer_uri| {
 6701                                        unchanged_buffers.contains(&buffer_uri)
 6702                                            || match old_diagnostic.source_kind {
 6703                                                DiagnosticSourceKind::Pulled => {
 6704                                                    !changed_buffers.contains(&buffer_uri)
 6705                                                }
 6706                                                DiagnosticSourceKind::Other
 6707                                                | DiagnosticSourceKind::Pushed => true,
 6708                                            }
 6709                                    })
 6710                            },
 6711                            cx,
 6712                        )
 6713                        .log_err();
 6714                }
 6715            })
 6716        })
 6717    }
 6718
 6719    pub fn document_colors(
 6720        &mut self,
 6721        fetch_strategy: LspFetchStrategy,
 6722        buffer: Entity<Buffer>,
 6723        cx: &mut Context<Self>,
 6724    ) -> Option<DocumentColorTask> {
 6725        let version_queried_for = buffer.read(cx).version();
 6726        let buffer_id = buffer.read(cx).remote_id();
 6727
 6728        match fetch_strategy {
 6729            LspFetchStrategy::IgnoreCache => {}
 6730            LspFetchStrategy::UseCache {
 6731                known_cache_version,
 6732            } => {
 6733                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6734                    && !version_queried_for.changed_since(&cached_data.colors_for_version) {
 6735                        let has_different_servers = self.as_local().is_some_and(|local| {
 6736                            local
 6737                                .buffers_opened_in_servers
 6738                                .get(&buffer_id)
 6739                                .cloned()
 6740                                .unwrap_or_default()
 6741                                != cached_data.colors.keys().copied().collect()
 6742                        });
 6743                        if !has_different_servers {
 6744                            if Some(cached_data.cache_version) == known_cache_version {
 6745                                return None;
 6746                            } else {
 6747                                return Some(
 6748                                    Task::ready(Ok(DocumentColors {
 6749                                        colors: cached_data
 6750                                            .colors
 6751                                            .values()
 6752                                            .flatten()
 6753                                            .cloned()
 6754                                            .collect(),
 6755                                        cache_version: Some(cached_data.cache_version),
 6756                                    }))
 6757                                    .shared(),
 6758                                );
 6759                            }
 6760                        }
 6761                    }
 6762            }
 6763        }
 6764
 6765        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6766        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6767            && !version_queried_for.changed_since(updating_for) {
 6768                return Some(running_update.clone());
 6769            }
 6770        let query_version_queried_for = version_queried_for.clone();
 6771        let new_task = cx
 6772            .spawn(async move |lsp_store, cx| {
 6773                cx.background_executor()
 6774                    .timer(Duration::from_millis(30))
 6775                    .await;
 6776                let fetched_colors = lsp_store
 6777                    .update(cx, |lsp_store, cx| {
 6778                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6779                    })?
 6780                    .await
 6781                    .context("fetching document colors")
 6782                    .map_err(Arc::new);
 6783                let fetched_colors = match fetched_colors {
 6784                    Ok(fetched_colors) => {
 6785                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6786                            && Some(true)
 6787                                == buffer
 6788                                    .update(cx, |buffer, _| {
 6789                                        buffer.version() != query_version_queried_for
 6790                                    })
 6791                                    .ok()
 6792                        {
 6793                            return Ok(DocumentColors::default());
 6794                        }
 6795                        fetched_colors
 6796                    }
 6797                    Err(e) => {
 6798                        lsp_store
 6799                            .update(cx, |lsp_store, _| {
 6800                                lsp_store
 6801                                    .lsp_document_colors
 6802                                    .entry(buffer_id)
 6803                                    .or_default()
 6804                                    .colors_update = None;
 6805                            })
 6806                            .ok();
 6807                        return Err(e);
 6808                    }
 6809                };
 6810
 6811                lsp_store
 6812                    .update(cx, |lsp_store, _| {
 6813                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6814
 6815                        if lsp_data.colors_for_version == query_version_queried_for {
 6816                            lsp_data.colors.extend(fetched_colors.clone());
 6817                            lsp_data.cache_version += 1;
 6818                        } else if !lsp_data
 6819                            .colors_for_version
 6820                            .changed_since(&query_version_queried_for)
 6821                        {
 6822                            lsp_data.colors_for_version = query_version_queried_for;
 6823                            lsp_data.colors = fetched_colors.clone();
 6824                            lsp_data.cache_version += 1;
 6825                        }
 6826                        lsp_data.colors_update = None;
 6827                        let colors = lsp_data
 6828                            .colors
 6829                            .values()
 6830                            .flatten()
 6831                            .cloned()
 6832                            .collect::<HashSet<_>>();
 6833                        DocumentColors {
 6834                            colors,
 6835                            cache_version: Some(lsp_data.cache_version),
 6836                        }
 6837                    })
 6838                    .map_err(Arc::new)
 6839            })
 6840            .shared();
 6841        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6842        Some(new_task)
 6843    }
 6844
 6845    fn fetch_document_colors_for_buffer(
 6846        &mut self,
 6847        buffer: &Entity<Buffer>,
 6848        cx: &mut Context<Self>,
 6849    ) -> Task<anyhow::Result<HashMap<LanguageServerId, HashSet<DocumentColor>>>> {
 6850        if let Some((client, project_id)) = self.upstream_client() {
 6851            let request = GetDocumentColor {};
 6852            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6853                return Task::ready(Ok(HashMap::default()));
 6854            }
 6855
 6856            let request_task = client.request(proto::MultiLspQuery {
 6857                project_id,
 6858                buffer_id: buffer.read(cx).remote_id().to_proto(),
 6859                version: serialize_version(&buffer.read(cx).version()),
 6860                strategy: Some(proto::multi_lsp_query::Strategy::All(
 6861                    proto::AllLanguageServers {},
 6862                )),
 6863                request: Some(proto::multi_lsp_query::Request::GetDocumentColor(
 6864                    request.to_proto(project_id, buffer.read(cx)),
 6865                )),
 6866            });
 6867            let buffer = buffer.clone();
 6868            cx.spawn(async move |project, cx| {
 6869                let Some(project) = project.upgrade() else {
 6870                    return Ok(HashMap::default());
 6871                };
 6872                let colors = join_all(
 6873                    request_task
 6874                        .await
 6875                        .log_err()
 6876                        .map(|response| response.responses)
 6877                        .unwrap_or_default()
 6878                        .into_iter()
 6879                        .filter_map(|lsp_response| match lsp_response.response? {
 6880                            proto::lsp_response::Response::GetDocumentColorResponse(response) => {
 6881                                Some((
 6882                                    LanguageServerId::from_proto(lsp_response.server_id),
 6883                                    response,
 6884                                ))
 6885                            }
 6886                            unexpected => {
 6887                                debug_panic!("Unexpected response: {unexpected:?}");
 6888                                None
 6889                            }
 6890                        })
 6891                        .map(|(server_id, color_response)| {
 6892                            let response = request.response_from_proto(
 6893                                color_response,
 6894                                project.clone(),
 6895                                buffer.clone(),
 6896                                cx.clone(),
 6897                            );
 6898                            async move { (server_id, response.await.log_err().unwrap_or_default()) }
 6899                        }),
 6900                )
 6901                .await
 6902                .into_iter()
 6903                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6904                    acc.entry(server_id)
 6905                        .or_insert_with(HashSet::default)
 6906                        .extend(colors);
 6907                    acc
 6908                });
 6909                Ok(colors)
 6910            })
 6911        } else {
 6912            let document_colors_task =
 6913                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6914            cx.background_spawn(async move {
 6915                Ok(document_colors_task
 6916                    .await
 6917                    .into_iter()
 6918                    .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6919                        acc.entry(server_id)
 6920                            .or_insert_with(HashSet::default)
 6921                            .extend(colors);
 6922                        acc
 6923                    })
 6924                    .into_iter()
 6925                    .collect())
 6926            })
 6927        }
 6928    }
 6929
 6930    pub fn signature_help<T: ToPointUtf16>(
 6931        &mut self,
 6932        buffer: &Entity<Buffer>,
 6933        position: T,
 6934        cx: &mut Context<Self>,
 6935    ) -> Task<Vec<SignatureHelp>> {
 6936        let position = position.to_point_utf16(buffer.read(cx));
 6937
 6938        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6939            let request = GetSignatureHelp { position };
 6940            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6941                return Task::ready(Vec::new());
 6942            }
 6943            let request_task = client.request(proto::MultiLspQuery {
 6944                buffer_id: buffer.read(cx).remote_id().into(),
 6945                version: serialize_version(&buffer.read(cx).version()),
 6946                project_id: upstream_project_id,
 6947                strategy: Some(proto::multi_lsp_query::Strategy::All(
 6948                    proto::AllLanguageServers {},
 6949                )),
 6950                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
 6951                    request.to_proto(upstream_project_id, buffer.read(cx)),
 6952                )),
 6953            });
 6954            let buffer = buffer.clone();
 6955            cx.spawn(async move |weak_project, cx| {
 6956                let Some(project) = weak_project.upgrade() else {
 6957                    return Vec::new();
 6958                };
 6959                join_all(
 6960                    request_task
 6961                        .await
 6962                        .log_err()
 6963                        .map(|response| response.responses)
 6964                        .unwrap_or_default()
 6965                        .into_iter()
 6966                        .filter_map(|lsp_response| match lsp_response.response? {
 6967                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
 6968                                Some(response)
 6969                            }
 6970                            unexpected => {
 6971                                debug_panic!("Unexpected response: {unexpected:?}");
 6972                                None
 6973                            }
 6974                        })
 6975                        .map(|signature_response| {
 6976                            let response = GetSignatureHelp { position }.response_from_proto(
 6977                                signature_response,
 6978                                project.clone(),
 6979                                buffer.clone(),
 6980                                cx.clone(),
 6981                            );
 6982                            async move { response.await.log_err().flatten() }
 6983                        }),
 6984                )
 6985                .await
 6986                .into_iter()
 6987                .flatten()
 6988                .collect()
 6989            })
 6990        } else {
 6991            let all_actions_task = self.request_multiple_lsp_locally(
 6992                buffer,
 6993                Some(position),
 6994                GetSignatureHelp { position },
 6995                cx,
 6996            );
 6997            cx.background_spawn(async move {
 6998                all_actions_task
 6999                    .await
 7000                    .into_iter()
 7001                    .flat_map(|(_, actions)| actions)
 7002                    .collect::<Vec<_>>()
 7003            })
 7004        }
 7005    }
 7006
 7007    pub fn hover(
 7008        &mut self,
 7009        buffer: &Entity<Buffer>,
 7010        position: PointUtf16,
 7011        cx: &mut Context<Self>,
 7012    ) -> Task<Vec<Hover>> {
 7013        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7014            let request = GetHover { position };
 7015            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7016                return Task::ready(Vec::new());
 7017            }
 7018            let request_task = client.request(proto::MultiLspQuery {
 7019                buffer_id: buffer.read(cx).remote_id().into(),
 7020                version: serialize_version(&buffer.read(cx).version()),
 7021                project_id: upstream_project_id,
 7022                strategy: Some(proto::multi_lsp_query::Strategy::All(
 7023                    proto::AllLanguageServers {},
 7024                )),
 7025                request: Some(proto::multi_lsp_query::Request::GetHover(
 7026                    request.to_proto(upstream_project_id, buffer.read(cx)),
 7027                )),
 7028            });
 7029            let buffer = buffer.clone();
 7030            cx.spawn(async move |weak_project, cx| {
 7031                let Some(project) = weak_project.upgrade() else {
 7032                    return Vec::new();
 7033                };
 7034                join_all(
 7035                    request_task
 7036                        .await
 7037                        .log_err()
 7038                        .map(|response| response.responses)
 7039                        .unwrap_or_default()
 7040                        .into_iter()
 7041                        .filter_map(|lsp_response| match lsp_response.response? {
 7042                            proto::lsp_response::Response::GetHoverResponse(response) => {
 7043                                Some(response)
 7044                            }
 7045                            unexpected => {
 7046                                debug_panic!("Unexpected response: {unexpected:?}");
 7047                                None
 7048                            }
 7049                        })
 7050                        .map(|hover_response| {
 7051                            let response = GetHover { position }.response_from_proto(
 7052                                hover_response,
 7053                                project.clone(),
 7054                                buffer.clone(),
 7055                                cx.clone(),
 7056                            );
 7057                            async move {
 7058                                response
 7059                                    .await
 7060                                    .log_err()
 7061                                    .flatten()
 7062                                    .and_then(remove_empty_hover_blocks)
 7063                            }
 7064                        }),
 7065                )
 7066                .await
 7067                .into_iter()
 7068                .flatten()
 7069                .collect()
 7070            })
 7071        } else {
 7072            let all_actions_task = self.request_multiple_lsp_locally(
 7073                buffer,
 7074                Some(position),
 7075                GetHover { position },
 7076                cx,
 7077            );
 7078            cx.background_spawn(async move {
 7079                all_actions_task
 7080                    .await
 7081                    .into_iter()
 7082                    .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7083                    .collect::<Vec<Hover>>()
 7084            })
 7085        }
 7086    }
 7087
 7088    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7089        let language_registry = self.languages.clone();
 7090
 7091        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7092            let request = upstream_client.request(proto::GetProjectSymbols {
 7093                project_id: *project_id,
 7094                query: query.to_string(),
 7095            });
 7096            cx.foreground_executor().spawn(async move {
 7097                let response = request.await?;
 7098                let mut symbols = Vec::new();
 7099                let core_symbols = response
 7100                    .symbols
 7101                    .into_iter()
 7102                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7103                    .collect::<Vec<_>>();
 7104                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7105                    .await;
 7106                Ok(symbols)
 7107            })
 7108        } else if let Some(local) = self.as_local() {
 7109            struct WorkspaceSymbolsResult {
 7110                server_id: LanguageServerId,
 7111                lsp_adapter: Arc<CachedLspAdapter>,
 7112                worktree: WeakEntity<Worktree>,
 7113                worktree_abs_path: Arc<Path>,
 7114                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7115            }
 7116
 7117            let mut requests = Vec::new();
 7118            let mut requested_servers = BTreeSet::new();
 7119            for (seed, state) in local.language_server_ids.iter() {
 7120                let Some(worktree_handle) = self
 7121                    .worktree_store
 7122                    .read(cx)
 7123                    .worktree_for_id(seed.worktree_id, cx)
 7124                else {
 7125                    continue;
 7126                };
 7127                let worktree = worktree_handle.read(cx);
 7128                if !worktree.is_visible() {
 7129                    continue;
 7130                }
 7131
 7132                if !requested_servers.insert(state.id) {
 7133                    continue;
 7134                }
 7135
 7136                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7137                    Some(LanguageServerState::Running {
 7138                        adapter, server, ..
 7139                    }) => (adapter.clone(), server),
 7140
 7141                    _ => continue,
 7142                };
 7143                let supports_workspace_symbol_request =
 7144                    match server.capabilities().workspace_symbol_provider {
 7145                        Some(OneOf::Left(supported)) => supported,
 7146                        Some(OneOf::Right(_)) => true,
 7147                        None => false,
 7148                    };
 7149                if !supports_workspace_symbol_request {
 7150                    continue;
 7151                }
 7152                let worktree_abs_path = worktree.abs_path().clone();
 7153                let worktree_handle = worktree_handle.clone();
 7154                let server_id = server.server_id();
 7155                requests.push(
 7156                        server
 7157                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7158                                lsp::WorkspaceSymbolParams {
 7159                                    query: query.to_string(),
 7160                                    ..Default::default()
 7161                                },
 7162                            )
 7163                            .map(move |response| {
 7164                                let lsp_symbols = response.into_response()
 7165                                    .context("workspace symbols request")
 7166                                    .log_err()
 7167                                    .flatten()
 7168                                    .map(|symbol_response| match symbol_response {
 7169                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7170                                            flat_responses.into_iter().map(|lsp_symbol| {
 7171                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7172                                            }).collect::<Vec<_>>()
 7173                                        }
 7174                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7175                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7176                                                let location = match lsp_symbol.location {
 7177                                                    OneOf::Left(location) => location,
 7178                                                    OneOf::Right(_) => {
 7179                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7180                                                        return None
 7181                                                    }
 7182                                                };
 7183                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7184                                            }).collect::<Vec<_>>()
 7185                                        }
 7186                                    }).unwrap_or_default();
 7187
 7188                                WorkspaceSymbolsResult {
 7189                                    server_id,
 7190                                    lsp_adapter,
 7191                                    worktree: worktree_handle.downgrade(),
 7192                                    worktree_abs_path,
 7193                                    lsp_symbols,
 7194                                }
 7195                            }),
 7196                    );
 7197            }
 7198
 7199            cx.spawn(async move |this, cx| {
 7200                let responses = futures::future::join_all(requests).await;
 7201                let this = match this.upgrade() {
 7202                    Some(this) => this,
 7203                    None => return Ok(Vec::new()),
 7204                };
 7205
 7206                let mut symbols = Vec::new();
 7207                for result in responses {
 7208                    let core_symbols = this.update(cx, |this, cx| {
 7209                        result
 7210                            .lsp_symbols
 7211                            .into_iter()
 7212                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7213                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7214                                let source_worktree = result.worktree.upgrade()?;
 7215                                let source_worktree_id = source_worktree.read(cx).id();
 7216
 7217                                let path;
 7218                                let worktree;
 7219                                if let Some((tree, rel_path)) =
 7220                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7221                                {
 7222                                    worktree = tree;
 7223                                    path = rel_path;
 7224                                } else {
 7225                                    worktree = source_worktree.clone();
 7226                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7227                                }
 7228
 7229                                let worktree_id = worktree.read(cx).id();
 7230                                let project_path = ProjectPath {
 7231                                    worktree_id,
 7232                                    path: path.into(),
 7233                                };
 7234                                let signature = this.symbol_signature(&project_path);
 7235                                Some(CoreSymbol {
 7236                                    source_language_server_id: result.server_id,
 7237                                    language_server_name: result.lsp_adapter.name.clone(),
 7238                                    source_worktree_id,
 7239                                    path: project_path,
 7240                                    kind: symbol_kind,
 7241                                    name: symbol_name,
 7242                                    range: range_from_lsp(symbol_location.range),
 7243                                    signature,
 7244                                })
 7245                            })
 7246                            .collect()
 7247                    })?;
 7248
 7249                    populate_labels_for_symbols(
 7250                        core_symbols,
 7251                        &language_registry,
 7252                        Some(result.lsp_adapter),
 7253                        &mut symbols,
 7254                    )
 7255                    .await;
 7256                }
 7257
 7258                Ok(symbols)
 7259            })
 7260        } else {
 7261            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7262        }
 7263    }
 7264
 7265    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7266        let mut summary = DiagnosticSummary::default();
 7267        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7268            summary.error_count += path_summary.error_count;
 7269            summary.warning_count += path_summary.warning_count;
 7270        }
 7271        summary
 7272    }
 7273
 7274    pub fn diagnostic_summaries<'a>(
 7275        &'a self,
 7276        include_ignored: bool,
 7277        cx: &'a App,
 7278    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7279        self.worktree_store
 7280            .read(cx)
 7281            .visible_worktrees(cx)
 7282            .filter_map(|worktree| {
 7283                let worktree = worktree.read(cx);
 7284                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7285            })
 7286            .flat_map(move |(worktree, summaries)| {
 7287                let worktree_id = worktree.id();
 7288                summaries
 7289                    .iter()
 7290                    .filter(move |(path, _)| {
 7291                        include_ignored
 7292                            || worktree
 7293                                .entry_for_path(path.as_ref())
 7294                                .map_or(false, |entry| !entry.is_ignored)
 7295                    })
 7296                    .flat_map(move |(path, summaries)| {
 7297                        summaries.iter().map(move |(server_id, summary)| {
 7298                            (
 7299                                ProjectPath {
 7300                                    worktree_id,
 7301                                    path: path.clone(),
 7302                                },
 7303                                *server_id,
 7304                                *summary,
 7305                            )
 7306                        })
 7307                    })
 7308            })
 7309    }
 7310
 7311    pub fn on_buffer_edited(
 7312        &mut self,
 7313        buffer: Entity<Buffer>,
 7314        cx: &mut Context<Self>,
 7315    ) -> Option<()> {
 7316        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7317            Some(
 7318                self.as_local()?
 7319                    .language_servers_for_buffer(buffer, cx)
 7320                    .map(|i| i.1.clone())
 7321                    .collect(),
 7322            )
 7323        })?;
 7324
 7325        let buffer = buffer.read(cx);
 7326        let file = File::from_dyn(buffer.file())?;
 7327        let abs_path = file.as_local()?.abs_path(cx);
 7328        let uri = lsp::Url::from_file_path(abs_path).unwrap();
 7329        let next_snapshot = buffer.text_snapshot();
 7330        for language_server in language_servers {
 7331            let language_server = language_server.clone();
 7332
 7333            let buffer_snapshots = self
 7334                .as_local_mut()
 7335                .unwrap()
 7336                .buffer_snapshots
 7337                .get_mut(&buffer.remote_id())
 7338                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7339            let previous_snapshot = buffer_snapshots.last()?;
 7340
 7341            let build_incremental_change = || {
 7342                buffer
 7343                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7344                        previous_snapshot.snapshot.version(),
 7345                    )
 7346                    .map(|edit| {
 7347                        let edit_start = edit.new.start.0;
 7348                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7349                        let new_text = next_snapshot
 7350                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7351                            .collect();
 7352                        lsp::TextDocumentContentChangeEvent {
 7353                            range: Some(lsp::Range::new(
 7354                                point_to_lsp(edit_start),
 7355                                point_to_lsp(edit_end),
 7356                            )),
 7357                            range_length: None,
 7358                            text: new_text,
 7359                        }
 7360                    })
 7361                    .collect()
 7362            };
 7363
 7364            let document_sync_kind = language_server
 7365                .capabilities()
 7366                .text_document_sync
 7367                .as_ref()
 7368                .and_then(|sync| match sync {
 7369                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7370                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7371                });
 7372
 7373            let content_changes: Vec<_> = match document_sync_kind {
 7374                Some(lsp::TextDocumentSyncKind::FULL) => {
 7375                    vec![lsp::TextDocumentContentChangeEvent {
 7376                        range: None,
 7377                        range_length: None,
 7378                        text: next_snapshot.text(),
 7379                    }]
 7380                }
 7381                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7382                _ => {
 7383                    #[cfg(any(test, feature = "test-support"))]
 7384                    {
 7385                        build_incremental_change()
 7386                    }
 7387
 7388                    #[cfg(not(any(test, feature = "test-support")))]
 7389                    {
 7390                        continue;
 7391                    }
 7392                }
 7393            };
 7394
 7395            let next_version = previous_snapshot.version + 1;
 7396            buffer_snapshots.push(LspBufferSnapshot {
 7397                version: next_version,
 7398                snapshot: next_snapshot.clone(),
 7399            });
 7400
 7401            language_server
 7402                .notify::<lsp::notification::DidChangeTextDocument>(
 7403                    &lsp::DidChangeTextDocumentParams {
 7404                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7405                            uri.clone(),
 7406                            next_version,
 7407                        ),
 7408                        content_changes,
 7409                    },
 7410                )
 7411                .ok();
 7412            self.pull_workspace_diagnostics(language_server.server_id());
 7413        }
 7414
 7415        None
 7416    }
 7417
 7418    pub fn on_buffer_saved(
 7419        &mut self,
 7420        buffer: Entity<Buffer>,
 7421        cx: &mut Context<Self>,
 7422    ) -> Option<()> {
 7423        let file = File::from_dyn(buffer.read(cx).file())?;
 7424        let worktree_id = file.worktree_id(cx);
 7425        let abs_path = file.as_local()?.abs_path(cx);
 7426        let text_document = lsp::TextDocumentIdentifier {
 7427            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7428        };
 7429        let local = self.as_local()?;
 7430
 7431        for server in local.language_servers_for_worktree(worktree_id) {
 7432            if let Some(include_text) = include_text(server.as_ref()) {
 7433                let text = if include_text {
 7434                    Some(buffer.read(cx).text())
 7435                } else {
 7436                    None
 7437                };
 7438                server
 7439                    .notify::<lsp::notification::DidSaveTextDocument>(
 7440                        &lsp::DidSaveTextDocumentParams {
 7441                            text_document: text_document.clone(),
 7442                            text,
 7443                        },
 7444                    )
 7445                    .ok();
 7446            }
 7447        }
 7448
 7449        let language_servers = buffer.update(cx, |buffer, cx| {
 7450            local.language_server_ids_for_buffer(buffer, cx)
 7451        });
 7452        for language_server_id in language_servers {
 7453            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7454        }
 7455
 7456        None
 7457    }
 7458
 7459    async fn refresh_workspace_configurations(
 7460        lsp_store: &WeakEntity<Self>,
 7461        fs: Arc<dyn Fs>,
 7462        cx: &mut AsyncApp,
 7463    ) {
 7464        maybe!(async move {
 7465            let mut refreshed_servers = HashSet::default();
 7466            let servers = lsp_store
 7467                .update(cx, |lsp_store, cx| {
 7468                    let local = lsp_store.as_local()?;
 7469
 7470                    let servers = local
 7471                        .language_server_ids
 7472                        .iter()
 7473                        .filter_map(|(seed, state)| {
 7474                            let worktree = lsp_store
 7475                                .worktree_store
 7476                                .read(cx)
 7477                                .worktree_for_id(seed.worktree_id, cx);
 7478                            let delegate: Arc<dyn LspAdapterDelegate> =
 7479                                worktree.map(|worktree| {
 7480                                    LocalLspAdapterDelegate::new(
 7481                                        local.languages.clone(),
 7482                                        &local.environment,
 7483                                        cx.weak_entity(),
 7484                                        &worktree,
 7485                                        local.http_client.clone(),
 7486                                        local.fs.clone(),
 7487                                        cx,
 7488                                    )
 7489                                })?;
 7490                            let server_id = state.id;
 7491
 7492                            let states = local.language_servers.get(&server_id)?;
 7493
 7494                            match states {
 7495                                LanguageServerState::Starting { .. } => None,
 7496                                LanguageServerState::Running {
 7497                                    adapter, server, ..
 7498                                } => {
 7499                                    let fs = fs.clone();
 7500
 7501                                    let adapter = adapter.clone();
 7502                                    let server = server.clone();
 7503                                    refreshed_servers.insert(server.name());
 7504                                    let toolchain = seed.toolchain.clone();
 7505                                    Some(cx.spawn(async move |_, cx| {
 7506                                        let settings =
 7507                                            LocalLspStore::workspace_configuration_for_adapter(
 7508                                                adapter.adapter.clone(),
 7509                                                fs.as_ref(),
 7510                                                &delegate,
 7511                                                toolchain,
 7512                                                cx,
 7513                                            )
 7514                                            .await
 7515                                            .ok()?;
 7516                                        server
 7517                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7518                                                &lsp::DidChangeConfigurationParams { settings },
 7519                                            )
 7520                                            .ok()?;
 7521                                        Some(())
 7522                                    }))
 7523                                }
 7524                            }
 7525                        })
 7526                        .collect::<Vec<_>>();
 7527
 7528                    Some(servers)
 7529                })
 7530                .ok()
 7531                .flatten()?;
 7532
 7533            log::info!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7534            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7535            // to stop and unregister its language server wrapper.
 7536            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7537            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7538            let _: Vec<Option<()>> = join_all(servers).await;
 7539
 7540            Some(())
 7541        })
 7542        .await;
 7543    }
 7544
 7545    fn maintain_workspace_config(
 7546        fs: Arc<dyn Fs>,
 7547        external_refresh_requests: watch::Receiver<()>,
 7548        cx: &mut Context<Self>,
 7549    ) -> Task<Result<()>> {
 7550        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7551        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7552
 7553        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7554            *settings_changed_tx.borrow_mut() = ();
 7555        });
 7556
 7557        let mut joint_future =
 7558            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7559        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7560        // - 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).
 7561        // - 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.
 7562        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7563        // - 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,
 7564        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7565        cx.spawn(async move |this, cx| {
 7566            while let Some(()) = joint_future.next().await {
 7567                this.update(cx, |this, cx| {
 7568                    this.refresh_server_tree(cx);
 7569                })
 7570                .ok();
 7571
 7572                Self::refresh_workspace_configurations(&this, fs.clone(), cx).await;
 7573            }
 7574
 7575            drop(settings_observation);
 7576            anyhow::Ok(())
 7577        })
 7578    }
 7579
 7580    pub fn language_servers_for_local_buffer<'a>(
 7581        &'a self,
 7582        buffer: &Buffer,
 7583        cx: &mut App,
 7584    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7585        let local = self.as_local();
 7586        let language_server_ids = local
 7587            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7588            .unwrap_or_default();
 7589
 7590        language_server_ids
 7591            .into_iter()
 7592            .filter_map(
 7593                move |server_id| match local?.language_servers.get(&server_id)? {
 7594                    LanguageServerState::Running {
 7595                        adapter, server, ..
 7596                    } => Some((adapter, server)),
 7597                    _ => None,
 7598                },
 7599            )
 7600    }
 7601
 7602    pub fn language_server_for_local_buffer<'a>(
 7603        &'a self,
 7604        buffer: &'a Buffer,
 7605        server_id: LanguageServerId,
 7606        cx: &'a mut App,
 7607    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7608        self.as_local()?
 7609            .language_servers_for_buffer(buffer, cx)
 7610            .find(|(_, s)| s.server_id() == server_id)
 7611    }
 7612
 7613    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7614        self.diagnostic_summaries.remove(&id_to_remove);
 7615        if let Some(local) = self.as_local_mut() {
 7616            let to_remove = local.remove_worktree(id_to_remove, cx);
 7617            for server in to_remove {
 7618                self.language_server_statuses.remove(&server);
 7619            }
 7620        }
 7621    }
 7622
 7623    pub fn shared(
 7624        &mut self,
 7625        project_id: u64,
 7626        downstream_client: AnyProtoClient,
 7627        _: &mut Context<Self>,
 7628    ) {
 7629        self.downstream_client = Some((downstream_client.clone(), project_id));
 7630
 7631        for (server_id, status) in &self.language_server_statuses {
 7632            if let Some(server) = self.language_server_for_id(*server_id) {
 7633                downstream_client
 7634                    .send(proto::StartLanguageServer {
 7635                        project_id,
 7636                        server: Some(proto::LanguageServer {
 7637                            id: server_id.to_proto(),
 7638                            name: status.name.to_string(),
 7639                            worktree_id: None,
 7640                        }),
 7641                        capabilities: serde_json::to_string(&server.capabilities())
 7642                            .expect("serializing server LSP capabilities"),
 7643                    })
 7644                    .log_err();
 7645            }
 7646        }
 7647    }
 7648
 7649    pub fn disconnected_from_host(&mut self) {
 7650        self.downstream_client.take();
 7651    }
 7652
 7653    pub fn disconnected_from_ssh_remote(&mut self) {
 7654        if let LspStoreMode::Remote(RemoteLspStore {
 7655            upstream_client, ..
 7656        }) = &mut self.mode
 7657        {
 7658            upstream_client.take();
 7659        }
 7660    }
 7661
 7662    pub(crate) fn set_language_server_statuses_from_proto(
 7663        &mut self,
 7664        language_servers: Vec<proto::LanguageServer>,
 7665        server_capabilities: Vec<String>,
 7666    ) {
 7667        self.language_server_statuses = language_servers
 7668            .into_iter()
 7669            .zip(server_capabilities)
 7670            .map(|(server, server_capabilities)| {
 7671                let server_id = LanguageServerId(server.id as usize);
 7672                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7673                    self.lsp_server_capabilities
 7674                        .insert(server_id, server_capabilities);
 7675                }
 7676                (
 7677                    server_id,
 7678                    LanguageServerStatus {
 7679                        name: LanguageServerName::from_proto(server.name),
 7680                        pending_work: Default::default(),
 7681                        has_pending_diagnostic_updates: false,
 7682                        progress_tokens: Default::default(),
 7683                    },
 7684                )
 7685            })
 7686            .collect();
 7687    }
 7688
 7689    #[cfg(test)]
 7690    pub fn update_diagnostic_entries(
 7691        &mut self,
 7692        server_id: LanguageServerId,
 7693        abs_path: PathBuf,
 7694        result_id: Option<String>,
 7695        version: Option<i32>,
 7696        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7697        cx: &mut Context<Self>,
 7698    ) -> anyhow::Result<()> {
 7699        self.merge_diagnostic_entries(
 7700            vec![DocumentDiagnosticsUpdate {
 7701                diagnostics: DocumentDiagnostics {
 7702                    diagnostics,
 7703                    document_abs_path: abs_path,
 7704                    version,
 7705                },
 7706                result_id,
 7707                server_id,
 7708                disk_based_sources: Cow::Borrowed(&[]),
 7709            }],
 7710            |_, _, _| false,
 7711            cx,
 7712        )?;
 7713        Ok(())
 7714    }
 7715
 7716    pub fn merge_diagnostic_entries<'a>(
 7717        &mut self,
 7718        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7719        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7720        cx: &mut Context<Self>,
 7721    ) -> anyhow::Result<()> {
 7722        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7723        let mut updated_diagnostics_paths = HashMap::default();
 7724        for mut update in diagnostic_updates {
 7725            let abs_path = &update.diagnostics.document_abs_path;
 7726            let server_id = update.server_id;
 7727            let Some((worktree, relative_path)) =
 7728                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7729            else {
 7730                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7731                return Ok(());
 7732            };
 7733
 7734            let worktree_id = worktree.read(cx).id();
 7735            let project_path = ProjectPath {
 7736                worktree_id,
 7737                path: relative_path.into(),
 7738            };
 7739
 7740            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7741                let snapshot = buffer_handle.read(cx).snapshot();
 7742                let buffer = buffer_handle.read(cx);
 7743                let reused_diagnostics = buffer
 7744                    .get_diagnostics(server_id)
 7745                    .into_iter()
 7746                    .flat_map(|diag| {
 7747                        diag.iter()
 7748                            .filter(|v| merge(buffer, &v.diagnostic, cx))
 7749                            .map(|v| {
 7750                                let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7751                                let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7752                                DiagnosticEntry {
 7753                                    range: start..end,
 7754                                    diagnostic: v.diagnostic.clone(),
 7755                                }
 7756                            })
 7757                    })
 7758                    .collect::<Vec<_>>();
 7759
 7760                self.as_local_mut()
 7761                    .context("cannot merge diagnostics on a remote LspStore")?
 7762                    .update_buffer_diagnostics(
 7763                        &buffer_handle,
 7764                        server_id,
 7765                        update.result_id,
 7766                        update.diagnostics.version,
 7767                        update.diagnostics.diagnostics.clone(),
 7768                        reused_diagnostics.clone(),
 7769                        cx,
 7770                    )?;
 7771
 7772                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7773            }
 7774
 7775            let updated = worktree.update(cx, |worktree, cx| {
 7776                self.update_worktree_diagnostics(
 7777                    worktree.id(),
 7778                    server_id,
 7779                    project_path.path.clone(),
 7780                    update.diagnostics.diagnostics,
 7781                    cx,
 7782                )
 7783            })?;
 7784            match updated {
 7785                ControlFlow::Continue(new_summary) => {
 7786                    if let Some((project_id, new_summary)) = new_summary {
 7787                        match &mut diagnostics_summary {
 7788                            Some(diagnostics_summary) => {
 7789                                diagnostics_summary
 7790                                    .more_summaries
 7791                                    .push(proto::DiagnosticSummary {
 7792                                        path: project_path.path.as_ref().to_proto(),
 7793                                        language_server_id: server_id.0 as u64,
 7794                                        error_count: new_summary.error_count,
 7795                                        warning_count: new_summary.warning_count,
 7796                                    })
 7797                            }
 7798                            None => {
 7799                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7800                                    project_id: project_id,
 7801                                    worktree_id: worktree_id.to_proto(),
 7802                                    summary: Some(proto::DiagnosticSummary {
 7803                                        path: project_path.path.as_ref().to_proto(),
 7804                                        language_server_id: server_id.0 as u64,
 7805                                        error_count: new_summary.error_count,
 7806                                        warning_count: new_summary.warning_count,
 7807                                    }),
 7808                                    more_summaries: Vec::new(),
 7809                                })
 7810                            }
 7811                        }
 7812                    }
 7813                    updated_diagnostics_paths
 7814                        .entry(server_id)
 7815                        .or_insert_with(Vec::new)
 7816                        .push(project_path);
 7817                }
 7818                ControlFlow::Break(()) => {}
 7819            }
 7820        }
 7821
 7822        if let Some((diagnostics_summary, (downstream_client, _))) =
 7823            diagnostics_summary.zip(self.downstream_client.as_ref())
 7824        {
 7825            downstream_client.send(diagnostics_summary).log_err();
 7826        }
 7827        for (server_id, paths) in updated_diagnostics_paths {
 7828            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7829        }
 7830        Ok(())
 7831    }
 7832
 7833    fn update_worktree_diagnostics(
 7834        &mut self,
 7835        worktree_id: WorktreeId,
 7836        server_id: LanguageServerId,
 7837        path_in_worktree: Arc<Path>,
 7838        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7839        _: &mut Context<Worktree>,
 7840    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7841        let local = match &mut self.mode {
 7842            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7843            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7844        };
 7845
 7846        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7847        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7848        let summaries_by_server_id = summaries_for_tree
 7849            .entry(path_in_worktree.clone())
 7850            .or_default();
 7851
 7852        let old_summary = summaries_by_server_id
 7853            .remove(&server_id)
 7854            .unwrap_or_default();
 7855
 7856        let new_summary = DiagnosticSummary::new(&diagnostics);
 7857        if new_summary.is_empty() {
 7858            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7859            {
 7860                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7861                    diagnostics_by_server_id.remove(ix);
 7862                }
 7863                if diagnostics_by_server_id.is_empty() {
 7864                    diagnostics_for_tree.remove(&path_in_worktree);
 7865                }
 7866            }
 7867        } else {
 7868            summaries_by_server_id.insert(server_id, new_summary);
 7869            let diagnostics_by_server_id = diagnostics_for_tree
 7870                .entry(path_in_worktree.clone())
 7871                .or_default();
 7872            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7873                Ok(ix) => {
 7874                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7875                }
 7876                Err(ix) => {
 7877                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7878                }
 7879            }
 7880        }
 7881
 7882        if !old_summary.is_empty() || !new_summary.is_empty() {
 7883            if let Some((_, project_id)) = &self.downstream_client {
 7884                Ok(ControlFlow::Continue(Some((
 7885                    *project_id,
 7886                    proto::DiagnosticSummary {
 7887                        path: path_in_worktree.to_proto(),
 7888                        language_server_id: server_id.0 as u64,
 7889                        error_count: new_summary.error_count as u32,
 7890                        warning_count: new_summary.warning_count as u32,
 7891                    },
 7892                ))))
 7893            } else {
 7894                Ok(ControlFlow::Continue(None))
 7895            }
 7896        } else {
 7897            Ok(ControlFlow::Break(()))
 7898        }
 7899    }
 7900
 7901    pub fn open_buffer_for_symbol(
 7902        &mut self,
 7903        symbol: &Symbol,
 7904        cx: &mut Context<Self>,
 7905    ) -> Task<Result<Entity<Buffer>>> {
 7906        if let Some((client, project_id)) = self.upstream_client() {
 7907            let request = client.request(proto::OpenBufferForSymbol {
 7908                project_id,
 7909                symbol: Some(Self::serialize_symbol(symbol)),
 7910            });
 7911            cx.spawn(async move |this, cx| {
 7912                let response = request.await?;
 7913                let buffer_id = BufferId::new(response.buffer_id)?;
 7914                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7915                    .await
 7916            })
 7917        } else if let Some(local) = self.as_local() {
 7918            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7919                seed.worktree_id == symbol.source_worktree_id
 7920                    && state.id == symbol.source_language_server_id
 7921                    && symbol.language_server_name == seed.name
 7922            });
 7923            if !is_valid {
 7924                return Task::ready(Err(anyhow!(
 7925                    "language server for worktree and language not found"
 7926                )));
 7927            };
 7928
 7929            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7930                .worktree_store
 7931                .read(cx)
 7932                .worktree_for_id(symbol.path.worktree_id, cx)
 7933                .map(|worktree| worktree.read(cx).abs_path())
 7934            {
 7935                worktree_abs_path
 7936            } else {
 7937                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7938            };
 7939
 7940            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7941            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
 7942                uri
 7943            } else {
 7944                return Task::ready(Err(anyhow!("invalid symbol path")));
 7945            };
 7946
 7947            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7948        } else {
 7949            Task::ready(Err(anyhow!("no upstream client or local store")))
 7950        }
 7951    }
 7952
 7953    pub(crate) fn open_local_buffer_via_lsp(
 7954        &mut self,
 7955        mut abs_path: lsp::Url,
 7956        language_server_id: LanguageServerId,
 7957        cx: &mut Context<Self>,
 7958    ) -> Task<Result<Entity<Buffer>>> {
 7959        cx.spawn(async move |lsp_store, cx| {
 7960            // Escape percent-encoded string.
 7961            let current_scheme = abs_path.scheme().to_owned();
 7962            let _ = abs_path.set_scheme("file");
 7963
 7964            let abs_path = abs_path
 7965                .to_file_path()
 7966                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7967            let p = abs_path.clone();
 7968            let yarn_worktree = lsp_store
 7969                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7970                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7971                        cx.spawn(async move |this, cx| {
 7972                            let t = this
 7973                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7974                                .ok()?;
 7975                            t.await
 7976                        })
 7977                    }),
 7978                    None => Task::ready(None),
 7979                })?
 7980                .await;
 7981            let (worktree_root_target, known_relative_path) =
 7982                if let Some((zip_root, relative_path)) = yarn_worktree {
 7983                    (zip_root, Some(relative_path))
 7984                } else {
 7985                    (Arc::<Path>::from(abs_path.as_path()), None)
 7986                };
 7987            let (worktree, relative_path) = if let Some(result) =
 7988                lsp_store.update(cx, |lsp_store, cx| {
 7989                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7990                        worktree_store.find_worktree(&worktree_root_target, cx)
 7991                    })
 7992                })? {
 7993                let relative_path =
 7994                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7995                (result.0, relative_path)
 7996            } else {
 7997                let worktree = lsp_store
 7998                    .update(cx, |lsp_store, cx| {
 7999                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8000                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8001                        })
 8002                    })?
 8003                    .await?;
 8004                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8005                    lsp_store
 8006                        .update(cx, |lsp_store, cx| {
 8007                            if let Some(local) = lsp_store.as_local_mut() {
 8008                                local.register_language_server_for_invisible_worktree(
 8009                                    &worktree,
 8010                                    language_server_id,
 8011                                    cx,
 8012                                )
 8013                            }
 8014                        })
 8015                        .ok();
 8016                }
 8017                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8018                let relative_path = if let Some(known_path) = known_relative_path {
 8019                    known_path
 8020                } else {
 8021                    abs_path.strip_prefix(worktree_root)?.into()
 8022                };
 8023                (worktree, relative_path)
 8024            };
 8025            let project_path = ProjectPath {
 8026                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8027                path: relative_path,
 8028            };
 8029            lsp_store
 8030                .update(cx, |lsp_store, cx| {
 8031                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8032                        buffer_store.open_buffer(project_path, cx)
 8033                    })
 8034                })?
 8035                .await
 8036        })
 8037    }
 8038
 8039    fn request_multiple_lsp_locally<P, R>(
 8040        &mut self,
 8041        buffer: &Entity<Buffer>,
 8042        position: Option<P>,
 8043        request: R,
 8044        cx: &mut Context<Self>,
 8045    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8046    where
 8047        P: ToOffset,
 8048        R: LspCommand + Clone,
 8049        <R::LspRequest as lsp::request::Request>::Result: Send,
 8050        <R::LspRequest as lsp::request::Request>::Params: Send,
 8051    {
 8052        let Some(local) = self.as_local() else {
 8053            return Task::ready(Vec::new());
 8054        };
 8055
 8056        let snapshot = buffer.read(cx).snapshot();
 8057        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8058
 8059        let server_ids = buffer.update(cx, |buffer, cx| {
 8060            local
 8061                .language_servers_for_buffer(buffer, cx)
 8062                .filter(|(adapter, _)| {
 8063                    scope
 8064                        .as_ref()
 8065                        .map(|scope| scope.language_allowed(&adapter.name))
 8066                        .unwrap_or(true)
 8067                })
 8068                .map(|(_, server)| server.server_id())
 8069                .filter(|server_id| {
 8070                    self.as_local().is_none_or(|local| {
 8071                        local
 8072                            .buffers_opened_in_servers
 8073                            .get(&snapshot.remote_id())
 8074                            .is_some_and(|servers| servers.contains(server_id))
 8075                    })
 8076                })
 8077                .collect::<Vec<_>>()
 8078        });
 8079
 8080        let mut response_results = server_ids
 8081            .into_iter()
 8082            .map(|server_id| {
 8083                let task = self.request_lsp(
 8084                    buffer.clone(),
 8085                    LanguageServerToQuery::Other(server_id),
 8086                    request.clone(),
 8087                    cx,
 8088                );
 8089                async move { (server_id, task.await) }
 8090            })
 8091            .collect::<FuturesUnordered<_>>();
 8092
 8093        cx.background_spawn(async move {
 8094            let mut responses = Vec::with_capacity(response_results.len());
 8095            while let Some((server_id, response_result)) = response_results.next().await {
 8096                if let Some(response) = response_result.log_err() {
 8097                    responses.push((server_id, response));
 8098                }
 8099            }
 8100            responses
 8101        })
 8102    }
 8103
 8104    async fn handle_lsp_command<T: LspCommand>(
 8105        this: Entity<Self>,
 8106        envelope: TypedEnvelope<T::ProtoRequest>,
 8107        mut cx: AsyncApp,
 8108    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8109    where
 8110        <T::LspRequest as lsp::request::Request>::Params: Send,
 8111        <T::LspRequest as lsp::request::Request>::Result: Send,
 8112    {
 8113        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8114        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8115        let buffer_handle = this.update(&mut cx, |this, cx| {
 8116            this.buffer_store.read(cx).get_existing(buffer_id)
 8117        })??;
 8118        let request = T::from_proto(
 8119            envelope.payload,
 8120            this.clone(),
 8121            buffer_handle.clone(),
 8122            cx.clone(),
 8123        )
 8124        .await?;
 8125        let response = this
 8126            .update(&mut cx, |this, cx| {
 8127                this.request_lsp(
 8128                    buffer_handle.clone(),
 8129                    LanguageServerToQuery::FirstCapable,
 8130                    request,
 8131                    cx,
 8132                )
 8133            })?
 8134            .await?;
 8135        this.update(&mut cx, |this, cx| {
 8136            Ok(T::response_to_proto(
 8137                response,
 8138                this,
 8139                sender_id,
 8140                &buffer_handle.read(cx).version(),
 8141                cx,
 8142            ))
 8143        })?
 8144    }
 8145
 8146    async fn handle_multi_lsp_query(
 8147        lsp_store: Entity<Self>,
 8148        envelope: TypedEnvelope<proto::MultiLspQuery>,
 8149        mut cx: AsyncApp,
 8150    ) -> Result<proto::MultiLspQueryResponse> {
 8151        let response_from_ssh = lsp_store.read_with(&mut cx, |this, _| {
 8152            let (upstream_client, project_id) = this.upstream_client()?;
 8153            let mut payload = envelope.payload.clone();
 8154            payload.project_id = project_id;
 8155
 8156            Some(upstream_client.request(payload))
 8157        })?;
 8158        if let Some(response_from_ssh) = response_from_ssh {
 8159            return response_from_ssh.await;
 8160        }
 8161
 8162        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8163        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8164        let version = deserialize_version(&envelope.payload.version);
 8165        let buffer = lsp_store.update(&mut cx, |this, cx| {
 8166            this.buffer_store.read(cx).get_existing(buffer_id)
 8167        })??;
 8168        buffer
 8169            .update(&mut cx, |buffer, _| {
 8170                buffer.wait_for_version(version.clone())
 8171            })?
 8172            .await?;
 8173        let buffer_version = buffer.read_with(&mut cx, |buffer, _| buffer.version())?;
 8174        match envelope
 8175            .payload
 8176            .strategy
 8177            .context("invalid request without the strategy")?
 8178        {
 8179            proto::multi_lsp_query::Strategy::All(_) => {
 8180                // currently, there's only one multiple language servers query strategy,
 8181                // so just ensure it's specified correctly
 8182            }
 8183        }
 8184        match envelope.payload.request {
 8185            Some(proto::multi_lsp_query::Request::GetHover(message)) => {
 8186                buffer
 8187                    .update(&mut cx, |buffer, _| {
 8188                        buffer.wait_for_version(deserialize_version(&message.version))
 8189                    })?
 8190                    .await?;
 8191                let get_hover =
 8192                    GetHover::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8193                        .await?;
 8194                let all_hovers = lsp_store
 8195                    .update(&mut cx, |this, cx| {
 8196                        this.request_multiple_lsp_locally(
 8197                            &buffer,
 8198                            Some(get_hover.position),
 8199                            get_hover,
 8200                            cx,
 8201                        )
 8202                    })?
 8203                    .await
 8204                    .into_iter()
 8205                    .filter_map(|(server_id, hover)| {
 8206                        Some((server_id, remove_empty_hover_blocks(hover?)?))
 8207                    });
 8208                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8209                    responses: all_hovers
 8210                        .map(|(server_id, hover)| proto::LspResponse {
 8211                            server_id: server_id.to_proto(),
 8212                            response: Some(proto::lsp_response::Response::GetHoverResponse(
 8213                                GetHover::response_to_proto(
 8214                                    Some(hover),
 8215                                    project,
 8216                                    sender_id,
 8217                                    &buffer_version,
 8218                                    cx,
 8219                                ),
 8220                            )),
 8221                        })
 8222                        .collect(),
 8223                })
 8224            }
 8225            Some(proto::multi_lsp_query::Request::GetCodeActions(message)) => {
 8226                buffer
 8227                    .update(&mut cx, |buffer, _| {
 8228                        buffer.wait_for_version(deserialize_version(&message.version))
 8229                    })?
 8230                    .await?;
 8231                let get_code_actions = GetCodeActions::from_proto(
 8232                    message,
 8233                    lsp_store.clone(),
 8234                    buffer.clone(),
 8235                    cx.clone(),
 8236                )
 8237                .await?;
 8238
 8239                let all_actions = lsp_store
 8240                    .update(&mut cx, |project, cx| {
 8241                        project.request_multiple_lsp_locally(
 8242                            &buffer,
 8243                            Some(get_code_actions.range.start),
 8244                            get_code_actions,
 8245                            cx,
 8246                        )
 8247                    })?
 8248                    .await
 8249                    .into_iter();
 8250
 8251                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8252                    responses: all_actions
 8253                        .map(|(server_id, code_actions)| proto::LspResponse {
 8254                            server_id: server_id.to_proto(),
 8255                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
 8256                                GetCodeActions::response_to_proto(
 8257                                    code_actions,
 8258                                    project,
 8259                                    sender_id,
 8260                                    &buffer_version,
 8261                                    cx,
 8262                                ),
 8263                            )),
 8264                        })
 8265                        .collect(),
 8266                })
 8267            }
 8268            Some(proto::multi_lsp_query::Request::GetSignatureHelp(message)) => {
 8269                buffer
 8270                    .update(&mut cx, |buffer, _| {
 8271                        buffer.wait_for_version(deserialize_version(&message.version))
 8272                    })?
 8273                    .await?;
 8274                let get_signature_help = GetSignatureHelp::from_proto(
 8275                    message,
 8276                    lsp_store.clone(),
 8277                    buffer.clone(),
 8278                    cx.clone(),
 8279                )
 8280                .await?;
 8281
 8282                let all_signatures = lsp_store
 8283                    .update(&mut cx, |project, cx| {
 8284                        project.request_multiple_lsp_locally(
 8285                            &buffer,
 8286                            Some(get_signature_help.position),
 8287                            get_signature_help,
 8288                            cx,
 8289                        )
 8290                    })?
 8291                    .await
 8292                    .into_iter();
 8293
 8294                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8295                    responses: all_signatures
 8296                        .map(|(server_id, signature_help)| proto::LspResponse {
 8297                            server_id: server_id.to_proto(),
 8298                            response: Some(
 8299                                proto::lsp_response::Response::GetSignatureHelpResponse(
 8300                                    GetSignatureHelp::response_to_proto(
 8301                                        signature_help,
 8302                                        project,
 8303                                        sender_id,
 8304                                        &buffer_version,
 8305                                        cx,
 8306                                    ),
 8307                                ),
 8308                            ),
 8309                        })
 8310                        .collect(),
 8311                })
 8312            }
 8313            Some(proto::multi_lsp_query::Request::GetCodeLens(message)) => {
 8314                buffer
 8315                    .update(&mut cx, |buffer, _| {
 8316                        buffer.wait_for_version(deserialize_version(&message.version))
 8317                    })?
 8318                    .await?;
 8319                let get_code_lens =
 8320                    GetCodeLens::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8321                        .await?;
 8322
 8323                let code_lens_actions = lsp_store
 8324                    .update(&mut cx, |project, cx| {
 8325                        project.request_multiple_lsp_locally(
 8326                            &buffer,
 8327                            None::<usize>,
 8328                            get_code_lens,
 8329                            cx,
 8330                        )
 8331                    })?
 8332                    .await
 8333                    .into_iter();
 8334
 8335                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8336                    responses: code_lens_actions
 8337                        .map(|(server_id, actions)| proto::LspResponse {
 8338                            server_id: server_id.to_proto(),
 8339                            response: Some(proto::lsp_response::Response::GetCodeLensResponse(
 8340                                GetCodeLens::response_to_proto(
 8341                                    actions,
 8342                                    project,
 8343                                    sender_id,
 8344                                    &buffer_version,
 8345                                    cx,
 8346                                ),
 8347                            )),
 8348                        })
 8349                        .collect(),
 8350                })
 8351            }
 8352            Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(message)) => {
 8353                buffer
 8354                    .update(&mut cx, |buffer, _| {
 8355                        buffer.wait_for_version(deserialize_version(&message.version))
 8356                    })?
 8357                    .await?;
 8358                lsp_store
 8359                    .update(&mut cx, |lsp_store, cx| {
 8360                        lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8361                    })?
 8362                    .await?;
 8363                // `pull_diagnostics_for_buffer` will merge in the new diagnostics and send them to the client.
 8364                // The client cannot merge anything into its non-local LspStore, so we do not need to return anything.
 8365                Ok(proto::MultiLspQueryResponse {
 8366                    responses: Vec::new(),
 8367                })
 8368            }
 8369            Some(proto::multi_lsp_query::Request::GetDocumentColor(message)) => {
 8370                buffer
 8371                    .update(&mut cx, |buffer, _| {
 8372                        buffer.wait_for_version(deserialize_version(&message.version))
 8373                    })?
 8374                    .await?;
 8375                let get_document_color = GetDocumentColor::from_proto(
 8376                    message,
 8377                    lsp_store.clone(),
 8378                    buffer.clone(),
 8379                    cx.clone(),
 8380                )
 8381                .await?;
 8382
 8383                let all_colors = lsp_store
 8384                    .update(&mut cx, |project, cx| {
 8385                        project.request_multiple_lsp_locally(
 8386                            &buffer,
 8387                            None::<usize>,
 8388                            get_document_color,
 8389                            cx,
 8390                        )
 8391                    })?
 8392                    .await
 8393                    .into_iter();
 8394
 8395                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8396                    responses: all_colors
 8397                        .map(|(server_id, colors)| proto::LspResponse {
 8398                            server_id: server_id.to_proto(),
 8399                            response: Some(
 8400                                proto::lsp_response::Response::GetDocumentColorResponse(
 8401                                    GetDocumentColor::response_to_proto(
 8402                                        colors,
 8403                                        project,
 8404                                        sender_id,
 8405                                        &buffer_version,
 8406                                        cx,
 8407                                    ),
 8408                                ),
 8409                            ),
 8410                        })
 8411                        .collect(),
 8412                })
 8413            }
 8414            Some(proto::multi_lsp_query::Request::GetDefinition(message)) => {
 8415                let get_definitions = GetDefinitions::from_proto(
 8416                    message,
 8417                    lsp_store.clone(),
 8418                    buffer.clone(),
 8419                    cx.clone(),
 8420                )
 8421                .await?;
 8422
 8423                let definitions = lsp_store
 8424                    .update(&mut cx, |project, cx| {
 8425                        project.request_multiple_lsp_locally(
 8426                            &buffer,
 8427                            Some(get_definitions.position),
 8428                            get_definitions,
 8429                            cx,
 8430                        )
 8431                    })?
 8432                    .await
 8433                    .into_iter();
 8434
 8435                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8436                    responses: definitions
 8437                        .map(|(server_id, definitions)| proto::LspResponse {
 8438                            server_id: server_id.to_proto(),
 8439                            response: Some(proto::lsp_response::Response::GetDefinitionResponse(
 8440                                GetDefinitions::response_to_proto(
 8441                                    definitions,
 8442                                    project,
 8443                                    sender_id,
 8444                                    &buffer_version,
 8445                                    cx,
 8446                                ),
 8447                            )),
 8448                        })
 8449                        .collect(),
 8450                })
 8451            }
 8452            Some(proto::multi_lsp_query::Request::GetDeclaration(message)) => {
 8453                let get_declarations = GetDeclarations::from_proto(
 8454                    message,
 8455                    lsp_store.clone(),
 8456                    buffer.clone(),
 8457                    cx.clone(),
 8458                )
 8459                .await?;
 8460
 8461                let declarations = lsp_store
 8462                    .update(&mut cx, |project, cx| {
 8463                        project.request_multiple_lsp_locally(
 8464                            &buffer,
 8465                            Some(get_declarations.position),
 8466                            get_declarations,
 8467                            cx,
 8468                        )
 8469                    })?
 8470                    .await
 8471                    .into_iter();
 8472
 8473                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8474                    responses: declarations
 8475                        .map(|(server_id, declarations)| proto::LspResponse {
 8476                            server_id: server_id.to_proto(),
 8477                            response: Some(proto::lsp_response::Response::GetDeclarationResponse(
 8478                                GetDeclarations::response_to_proto(
 8479                                    declarations,
 8480                                    project,
 8481                                    sender_id,
 8482                                    &buffer_version,
 8483                                    cx,
 8484                                ),
 8485                            )),
 8486                        })
 8487                        .collect(),
 8488                })
 8489            }
 8490            Some(proto::multi_lsp_query::Request::GetTypeDefinition(message)) => {
 8491                let get_type_definitions = GetTypeDefinitions::from_proto(
 8492                    message,
 8493                    lsp_store.clone(),
 8494                    buffer.clone(),
 8495                    cx.clone(),
 8496                )
 8497                .await?;
 8498
 8499                let type_definitions = lsp_store
 8500                    .update(&mut cx, |project, cx| {
 8501                        project.request_multiple_lsp_locally(
 8502                            &buffer,
 8503                            Some(get_type_definitions.position),
 8504                            get_type_definitions,
 8505                            cx,
 8506                        )
 8507                    })?
 8508                    .await
 8509                    .into_iter();
 8510
 8511                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8512                    responses: type_definitions
 8513                        .map(|(server_id, type_definitions)| proto::LspResponse {
 8514                            server_id: server_id.to_proto(),
 8515                            response: Some(
 8516                                proto::lsp_response::Response::GetTypeDefinitionResponse(
 8517                                    GetTypeDefinitions::response_to_proto(
 8518                                        type_definitions,
 8519                                        project,
 8520                                        sender_id,
 8521                                        &buffer_version,
 8522                                        cx,
 8523                                    ),
 8524                                ),
 8525                            ),
 8526                        })
 8527                        .collect(),
 8528                })
 8529            }
 8530            Some(proto::multi_lsp_query::Request::GetImplementation(message)) => {
 8531                let get_implementations = GetImplementations::from_proto(
 8532                    message,
 8533                    lsp_store.clone(),
 8534                    buffer.clone(),
 8535                    cx.clone(),
 8536                )
 8537                .await?;
 8538
 8539                let implementations = lsp_store
 8540                    .update(&mut cx, |project, cx| {
 8541                        project.request_multiple_lsp_locally(
 8542                            &buffer,
 8543                            Some(get_implementations.position),
 8544                            get_implementations,
 8545                            cx,
 8546                        )
 8547                    })?
 8548                    .await
 8549                    .into_iter();
 8550
 8551                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8552                    responses: implementations
 8553                        .map(|(server_id, implementations)| proto::LspResponse {
 8554                            server_id: server_id.to_proto(),
 8555                            response: Some(
 8556                                proto::lsp_response::Response::GetImplementationResponse(
 8557                                    GetImplementations::response_to_proto(
 8558                                        implementations,
 8559                                        project,
 8560                                        sender_id,
 8561                                        &buffer_version,
 8562                                        cx,
 8563                                    ),
 8564                                ),
 8565                            ),
 8566                        })
 8567                        .collect(),
 8568                })
 8569            }
 8570            Some(proto::multi_lsp_query::Request::GetReferences(message)) => {
 8571                let get_references = GetReferences::from_proto(
 8572                    message,
 8573                    lsp_store.clone(),
 8574                    buffer.clone(),
 8575                    cx.clone(),
 8576                )
 8577                .await?;
 8578
 8579                let references = lsp_store
 8580                    .update(&mut cx, |project, cx| {
 8581                        project.request_multiple_lsp_locally(
 8582                            &buffer,
 8583                            Some(get_references.position),
 8584                            get_references,
 8585                            cx,
 8586                        )
 8587                    })?
 8588                    .await
 8589                    .into_iter();
 8590
 8591                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8592                    responses: references
 8593                        .map(|(server_id, references)| proto::LspResponse {
 8594                            server_id: server_id.to_proto(),
 8595                            response: Some(proto::lsp_response::Response::GetReferencesResponse(
 8596                                GetReferences::response_to_proto(
 8597                                    references,
 8598                                    project,
 8599                                    sender_id,
 8600                                    &buffer_version,
 8601                                    cx,
 8602                                ),
 8603                            )),
 8604                        })
 8605                        .collect(),
 8606                })
 8607            }
 8608            None => anyhow::bail!("empty multi lsp query request"),
 8609        }
 8610    }
 8611
 8612    async fn handle_apply_code_action(
 8613        this: Entity<Self>,
 8614        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8615        mut cx: AsyncApp,
 8616    ) -> Result<proto::ApplyCodeActionResponse> {
 8617        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8618        let action =
 8619            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8620        let apply_code_action = this.update(&mut cx, |this, cx| {
 8621            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8622            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8623            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8624        })??;
 8625
 8626        let project_transaction = apply_code_action.await?;
 8627        let project_transaction = this.update(&mut cx, |this, cx| {
 8628            this.buffer_store.update(cx, |buffer_store, cx| {
 8629                buffer_store.serialize_project_transaction_for_peer(
 8630                    project_transaction,
 8631                    sender_id,
 8632                    cx,
 8633                )
 8634            })
 8635        })?;
 8636        Ok(proto::ApplyCodeActionResponse {
 8637            transaction: Some(project_transaction),
 8638        })
 8639    }
 8640
 8641    async fn handle_register_buffer_with_language_servers(
 8642        this: Entity<Self>,
 8643        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8644        mut cx: AsyncApp,
 8645    ) -> Result<proto::Ack> {
 8646        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8647        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8648        this.update(&mut cx, |this, cx| {
 8649            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8650                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8651                    project_id: upstream_project_id,
 8652                    buffer_id: buffer_id.to_proto(),
 8653                    only_servers: envelope.payload.only_servers,
 8654                });
 8655            }
 8656
 8657            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8658                anyhow::bail!("buffer is not open");
 8659            };
 8660
 8661            let handle = this.register_buffer_with_language_servers(
 8662                &buffer,
 8663                envelope
 8664                    .payload
 8665                    .only_servers
 8666                    .into_iter()
 8667                    .filter_map(|selector| {
 8668                        Some(match selector.selector? {
 8669                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8670                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8671                            }
 8672                            proto::language_server_selector::Selector::Name(name) => {
 8673                                LanguageServerSelector::Name(LanguageServerName(
 8674                                    SharedString::from(name),
 8675                                ))
 8676                            }
 8677                        })
 8678                    })
 8679                    .collect(),
 8680                false,
 8681                cx,
 8682            );
 8683            this.buffer_store().update(cx, |buffer_store, _| {
 8684                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8685            });
 8686
 8687            Ok(())
 8688        })??;
 8689        Ok(proto::Ack {})
 8690    }
 8691
 8692    async fn handle_rename_project_entry(
 8693        this: Entity<Self>,
 8694        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8695        mut cx: AsyncApp,
 8696    ) -> Result<proto::ProjectEntryResponse> {
 8697        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8698        let (worktree_id, worktree, old_path, is_dir) = this
 8699            .update(&mut cx, |this, cx| {
 8700                this.worktree_store
 8701                    .read(cx)
 8702                    .worktree_and_entry_for_id(entry_id, cx)
 8703                    .map(|(worktree, entry)| {
 8704                        (
 8705                            worktree.read(cx).id(),
 8706                            worktree,
 8707                            entry.path.clone(),
 8708                            entry.is_dir(),
 8709                        )
 8710                    })
 8711            })?
 8712            .context("worktree not found")?;
 8713        let (old_abs_path, new_abs_path) = {
 8714            let root_path = worktree.read_with(&mut cx, |this, _| this.abs_path())?;
 8715            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8716            (root_path.join(&old_path), root_path.join(&new_path))
 8717        };
 8718
 8719        Self::will_rename_entry(
 8720            this.downgrade(),
 8721            worktree_id,
 8722            &old_abs_path,
 8723            &new_abs_path,
 8724            is_dir,
 8725            cx.clone(),
 8726        )
 8727        .await;
 8728        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8729        this.read_with(&mut cx, |this, _| {
 8730            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8731        })
 8732        .ok();
 8733        response
 8734    }
 8735
 8736    async fn handle_update_diagnostic_summary(
 8737        this: Entity<Self>,
 8738        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8739        mut cx: AsyncApp,
 8740    ) -> Result<()> {
 8741        this.update(&mut cx, |lsp_store, cx| {
 8742            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8743            let mut updated_diagnostics_paths = HashMap::default();
 8744            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8745            for message_summary in envelope
 8746                .payload
 8747                .summary
 8748                .into_iter()
 8749                .chain(envelope.payload.more_summaries)
 8750            {
 8751                let project_path = ProjectPath {
 8752                    worktree_id,
 8753                    path: Arc::<Path>::from_proto(message_summary.path),
 8754                };
 8755                let path = project_path.path.clone();
 8756                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8757                let summary = DiagnosticSummary {
 8758                    error_count: message_summary.error_count as usize,
 8759                    warning_count: message_summary.warning_count as usize,
 8760                };
 8761
 8762                if summary.is_empty() {
 8763                    if let Some(worktree_summaries) =
 8764                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8765                        && let Some(summaries) = worktree_summaries.get_mut(&path) {
 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        mut cx: AsyncApp,
 8963    ) -> Result<proto::Ack> {
 8964        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8965        lsp_store.read_with(&mut 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        mut cx: AsyncApp,
 9015    ) -> Result<proto::Ack> {
 9016        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9017        lsp_store.read_with(&mut 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            .map_or(false, |disk_based_token| {
 9338                token.starts_with(disk_based_token)
 9339            });
 9340
 9341        match progress {
 9342            lsp::WorkDoneProgress::Begin(report) => {
 9343                if is_disk_based_diagnostics_progress {
 9344                    self.disk_based_diagnostics_started(language_server_id, cx);
 9345                }
 9346                self.on_lsp_work_start(
 9347                    language_server_id,
 9348                    token.clone(),
 9349                    LanguageServerProgress {
 9350                        title: Some(report.title),
 9351                        is_disk_based_diagnostics_progress,
 9352                        is_cancellable: report.cancellable.unwrap_or(false),
 9353                        message: report.message.clone(),
 9354                        percentage: report.percentage.map(|p| p as usize),
 9355                        last_update_at: cx.background_executor().now(),
 9356                    },
 9357                    cx,
 9358                );
 9359            }
 9360            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9361                language_server_id,
 9362                token,
 9363                LanguageServerProgress {
 9364                    title: None,
 9365                    is_disk_based_diagnostics_progress,
 9366                    is_cancellable: report.cancellable.unwrap_or(false),
 9367                    message: report.message,
 9368                    percentage: report.percentage.map(|p| p as usize),
 9369                    last_update_at: cx.background_executor().now(),
 9370                },
 9371                cx,
 9372            ),
 9373            lsp::WorkDoneProgress::End(_) => {
 9374                language_server_status.progress_tokens.remove(&token);
 9375                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9376                if is_disk_based_diagnostics_progress {
 9377                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9378                }
 9379            }
 9380        }
 9381    }
 9382
 9383    fn on_lsp_work_start(
 9384        &mut self,
 9385        language_server_id: LanguageServerId,
 9386        token: String,
 9387        progress: LanguageServerProgress,
 9388        cx: &mut Context<Self>,
 9389    ) {
 9390        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9391            status.pending_work.insert(token.clone(), progress.clone());
 9392            cx.notify();
 9393        }
 9394        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9395            language_server_id,
 9396            name: self
 9397                .language_server_adapter_for_id(language_server_id)
 9398                .map(|adapter| adapter.name()),
 9399            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9400                token,
 9401                title: progress.title,
 9402                message: progress.message,
 9403                percentage: progress.percentage.map(|p| p as u32),
 9404                is_cancellable: Some(progress.is_cancellable),
 9405            }),
 9406        })
 9407    }
 9408
 9409    fn on_lsp_work_progress(
 9410        &mut self,
 9411        language_server_id: LanguageServerId,
 9412        token: String,
 9413        progress: LanguageServerProgress,
 9414        cx: &mut Context<Self>,
 9415    ) {
 9416        let mut did_update = false;
 9417        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9418            match status.pending_work.entry(token.clone()) {
 9419                btree_map::Entry::Vacant(entry) => {
 9420                    entry.insert(progress.clone());
 9421                    did_update = true;
 9422                }
 9423                btree_map::Entry::Occupied(mut entry) => {
 9424                    let entry = entry.get_mut();
 9425                    if (progress.last_update_at - entry.last_update_at)
 9426                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9427                    {
 9428                        entry.last_update_at = progress.last_update_at;
 9429                        if progress.message.is_some() {
 9430                            entry.message = progress.message.clone();
 9431                        }
 9432                        if progress.percentage.is_some() {
 9433                            entry.percentage = progress.percentage;
 9434                        }
 9435                        if progress.is_cancellable != entry.is_cancellable {
 9436                            entry.is_cancellable = progress.is_cancellable;
 9437                        }
 9438                        did_update = true;
 9439                    }
 9440                }
 9441            }
 9442        }
 9443
 9444        if did_update {
 9445            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9446                language_server_id,
 9447                name: self
 9448                    .language_server_adapter_for_id(language_server_id)
 9449                    .map(|adapter| adapter.name()),
 9450                message: proto::update_language_server::Variant::WorkProgress(
 9451                    proto::LspWorkProgress {
 9452                        token,
 9453                        message: progress.message,
 9454                        percentage: progress.percentage.map(|p| p as u32),
 9455                        is_cancellable: Some(progress.is_cancellable),
 9456                    },
 9457                ),
 9458            })
 9459        }
 9460    }
 9461
 9462    fn on_lsp_work_end(
 9463        &mut self,
 9464        language_server_id: LanguageServerId,
 9465        token: String,
 9466        cx: &mut Context<Self>,
 9467    ) {
 9468        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9469            if let Some(work) = status.pending_work.remove(&token)
 9470                && !work.is_disk_based_diagnostics_progress {
 9471                    cx.emit(LspStoreEvent::RefreshInlayHints);
 9472                }
 9473            cx.notify();
 9474        }
 9475
 9476        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9477            language_server_id,
 9478            name: self
 9479                .language_server_adapter_for_id(language_server_id)
 9480                .map(|adapter| adapter.name()),
 9481            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9482        })
 9483    }
 9484
 9485    pub async fn handle_resolve_completion_documentation(
 9486        this: Entity<Self>,
 9487        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9488        mut cx: AsyncApp,
 9489    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9490        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9491
 9492        let completion = this
 9493            .read_with(&cx, |this, cx| {
 9494                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9495                let server = this
 9496                    .language_server_for_id(id)
 9497                    .with_context(|| format!("No language server {id}"))?;
 9498
 9499                anyhow::Ok(cx.background_spawn(async move {
 9500                    let can_resolve = server
 9501                        .capabilities()
 9502                        .completion_provider
 9503                        .as_ref()
 9504                        .and_then(|options| options.resolve_provider)
 9505                        .unwrap_or(false);
 9506                    if can_resolve {
 9507                        server
 9508                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9509                            .await
 9510                            .into_response()
 9511                            .context("resolve completion item")
 9512                    } else {
 9513                        anyhow::Ok(lsp_completion)
 9514                    }
 9515                }))
 9516            })??
 9517            .await?;
 9518
 9519        let mut documentation_is_markdown = false;
 9520        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9521        let documentation = match completion.documentation {
 9522            Some(lsp::Documentation::String(text)) => text,
 9523
 9524            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9525                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9526                value
 9527            }
 9528
 9529            _ => String::new(),
 9530        };
 9531
 9532        // If we have a new buffer_id, that means we're talking to a new client
 9533        // and want to check for new text_edits in the completion too.
 9534        let mut old_replace_start = None;
 9535        let mut old_replace_end = None;
 9536        let mut old_insert_start = None;
 9537        let mut old_insert_end = None;
 9538        let mut new_text = String::default();
 9539        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9540            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9541                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9542                anyhow::Ok(buffer.read(cx).snapshot())
 9543            })??;
 9544
 9545            if let Some(text_edit) = completion.text_edit.as_ref() {
 9546                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9547
 9548                if let Some(mut edit) = edit {
 9549                    LineEnding::normalize(&mut edit.new_text);
 9550
 9551                    new_text = edit.new_text;
 9552                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9553                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9554                    if let Some(insert_range) = edit.insert_range {
 9555                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9556                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9557                    }
 9558                }
 9559            }
 9560        }
 9561
 9562        Ok(proto::ResolveCompletionDocumentationResponse {
 9563            documentation,
 9564            documentation_is_markdown,
 9565            old_replace_start,
 9566            old_replace_end,
 9567            new_text,
 9568            lsp_completion,
 9569            old_insert_start,
 9570            old_insert_end,
 9571        })
 9572    }
 9573
 9574    async fn handle_on_type_formatting(
 9575        this: Entity<Self>,
 9576        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9577        mut cx: AsyncApp,
 9578    ) -> Result<proto::OnTypeFormattingResponse> {
 9579        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9580            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9581            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9582            let position = envelope
 9583                .payload
 9584                .position
 9585                .and_then(deserialize_anchor)
 9586                .context("invalid position")?;
 9587            anyhow::Ok(this.apply_on_type_formatting(
 9588                buffer,
 9589                position,
 9590                envelope.payload.trigger.clone(),
 9591                cx,
 9592            ))
 9593        })??;
 9594
 9595        let transaction = on_type_formatting
 9596            .await?
 9597            .as_ref()
 9598            .map(language::proto::serialize_transaction);
 9599        Ok(proto::OnTypeFormattingResponse { transaction })
 9600    }
 9601
 9602    async fn handle_refresh_inlay_hints(
 9603        this: Entity<Self>,
 9604        _: TypedEnvelope<proto::RefreshInlayHints>,
 9605        mut cx: AsyncApp,
 9606    ) -> Result<proto::Ack> {
 9607        this.update(&mut cx, |_, cx| {
 9608            cx.emit(LspStoreEvent::RefreshInlayHints);
 9609        })?;
 9610        Ok(proto::Ack {})
 9611    }
 9612
 9613    async fn handle_pull_workspace_diagnostics(
 9614        lsp_store: Entity<Self>,
 9615        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9616        mut cx: AsyncApp,
 9617    ) -> Result<proto::Ack> {
 9618        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9619        lsp_store.update(&mut cx, |lsp_store, _| {
 9620            lsp_store.pull_workspace_diagnostics(server_id);
 9621        })?;
 9622        Ok(proto::Ack {})
 9623    }
 9624
 9625    async fn handle_inlay_hints(
 9626        this: Entity<Self>,
 9627        envelope: TypedEnvelope<proto::InlayHints>,
 9628        mut cx: AsyncApp,
 9629    ) -> Result<proto::InlayHintsResponse> {
 9630        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9631        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9632        let buffer = this.update(&mut cx, |this, cx| {
 9633            this.buffer_store.read(cx).get_existing(buffer_id)
 9634        })??;
 9635        buffer
 9636            .update(&mut cx, |buffer, _| {
 9637                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9638            })?
 9639            .await
 9640            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9641
 9642        let start = envelope
 9643            .payload
 9644            .start
 9645            .and_then(deserialize_anchor)
 9646            .context("missing range start")?;
 9647        let end = envelope
 9648            .payload
 9649            .end
 9650            .and_then(deserialize_anchor)
 9651            .context("missing range end")?;
 9652        let buffer_hints = this
 9653            .update(&mut cx, |lsp_store, cx| {
 9654                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9655            })?
 9656            .await
 9657            .context("inlay hints fetch")?;
 9658
 9659        this.update(&mut cx, |project, cx| {
 9660            InlayHints::response_to_proto(
 9661                buffer_hints,
 9662                project,
 9663                sender_id,
 9664                &buffer.read(cx).version(),
 9665                cx,
 9666            )
 9667        })
 9668    }
 9669
 9670    async fn handle_get_color_presentation(
 9671        lsp_store: Entity<Self>,
 9672        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9673        mut cx: AsyncApp,
 9674    ) -> Result<proto::GetColorPresentationResponse> {
 9675        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9676        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9677            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9678        })??;
 9679
 9680        let color = envelope
 9681            .payload
 9682            .color
 9683            .context("invalid color resolve request")?;
 9684        let start = color
 9685            .lsp_range_start
 9686            .context("invalid color resolve request")?;
 9687        let end = color
 9688            .lsp_range_end
 9689            .context("invalid color resolve request")?;
 9690
 9691        let color = DocumentColor {
 9692            lsp_range: lsp::Range {
 9693                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9694                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9695            },
 9696            color: lsp::Color {
 9697                red: color.red,
 9698                green: color.green,
 9699                blue: color.blue,
 9700                alpha: color.alpha,
 9701            },
 9702            resolved: false,
 9703            color_presentations: Vec::new(),
 9704        };
 9705        let resolved_color = lsp_store
 9706            .update(&mut cx, |lsp_store, cx| {
 9707                lsp_store.resolve_color_presentation(
 9708                    color,
 9709                    buffer.clone(),
 9710                    LanguageServerId(envelope.payload.server_id as usize),
 9711                    cx,
 9712                )
 9713            })?
 9714            .await
 9715            .context("resolving color presentation")?;
 9716
 9717        Ok(proto::GetColorPresentationResponse {
 9718            presentations: resolved_color
 9719                .color_presentations
 9720                .into_iter()
 9721                .map(|presentation| proto::ColorPresentation {
 9722                    label: presentation.label.to_string(),
 9723                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9724                    additional_text_edits: presentation
 9725                        .additional_text_edits
 9726                        .into_iter()
 9727                        .map(serialize_lsp_edit)
 9728                        .collect(),
 9729                })
 9730                .collect(),
 9731        })
 9732    }
 9733
 9734    async fn handle_resolve_inlay_hint(
 9735        this: Entity<Self>,
 9736        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9737        mut cx: AsyncApp,
 9738    ) -> Result<proto::ResolveInlayHintResponse> {
 9739        let proto_hint = envelope
 9740            .payload
 9741            .hint
 9742            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9743        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9744            .context("resolved proto inlay hint conversion")?;
 9745        let buffer = this.update(&mut cx, |this, cx| {
 9746            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9747            this.buffer_store.read(cx).get_existing(buffer_id)
 9748        })??;
 9749        let response_hint = this
 9750            .update(&mut cx, |this, cx| {
 9751                this.resolve_inlay_hint(
 9752                    hint,
 9753                    buffer,
 9754                    LanguageServerId(envelope.payload.language_server_id as usize),
 9755                    cx,
 9756                )
 9757            })?
 9758            .await
 9759            .context("inlay hints fetch")?;
 9760        Ok(proto::ResolveInlayHintResponse {
 9761            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9762        })
 9763    }
 9764
 9765    async fn handle_refresh_code_lens(
 9766        this: Entity<Self>,
 9767        _: TypedEnvelope<proto::RefreshCodeLens>,
 9768        mut cx: AsyncApp,
 9769    ) -> Result<proto::Ack> {
 9770        this.update(&mut cx, |_, cx| {
 9771            cx.emit(LspStoreEvent::RefreshCodeLens);
 9772        })?;
 9773        Ok(proto::Ack {})
 9774    }
 9775
 9776    async fn handle_open_buffer_for_symbol(
 9777        this: Entity<Self>,
 9778        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9779        mut cx: AsyncApp,
 9780    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9781        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9782        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9783        let symbol = Self::deserialize_symbol(symbol)?;
 9784        let symbol = this.read_with(&mut cx, |this, _| {
 9785            let signature = this.symbol_signature(&symbol.path);
 9786            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9787            Ok(symbol)
 9788        })??;
 9789        let buffer = this
 9790            .update(&mut cx, |this, cx| {
 9791                this.open_buffer_for_symbol(
 9792                    &Symbol {
 9793                        language_server_name: symbol.language_server_name,
 9794                        source_worktree_id: symbol.source_worktree_id,
 9795                        source_language_server_id: symbol.source_language_server_id,
 9796                        path: symbol.path,
 9797                        name: symbol.name,
 9798                        kind: symbol.kind,
 9799                        range: symbol.range,
 9800                        signature: symbol.signature,
 9801                        label: CodeLabel {
 9802                            text: Default::default(),
 9803                            runs: Default::default(),
 9804                            filter_range: Default::default(),
 9805                        },
 9806                    },
 9807                    cx,
 9808                )
 9809            })?
 9810            .await?;
 9811
 9812        this.update(&mut cx, |this, cx| {
 9813            let is_private = buffer
 9814                .read(cx)
 9815                .file()
 9816                .map(|f| f.is_private())
 9817                .unwrap_or_default();
 9818            if is_private {
 9819                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9820            } else {
 9821                this.buffer_store
 9822                    .update(cx, |buffer_store, cx| {
 9823                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9824                    })
 9825                    .detach_and_log_err(cx);
 9826                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9827                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9828            }
 9829        })?
 9830    }
 9831
 9832    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9833        let mut hasher = Sha256::new();
 9834        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9835        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9836        hasher.update(self.nonce.to_be_bytes());
 9837        hasher.finalize().as_slice().try_into().unwrap()
 9838    }
 9839
 9840    pub async fn handle_get_project_symbols(
 9841        this: Entity<Self>,
 9842        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9843        mut cx: AsyncApp,
 9844    ) -> Result<proto::GetProjectSymbolsResponse> {
 9845        let symbols = this
 9846            .update(&mut cx, |this, cx| {
 9847                this.symbols(&envelope.payload.query, cx)
 9848            })?
 9849            .await?;
 9850
 9851        Ok(proto::GetProjectSymbolsResponse {
 9852            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9853        })
 9854    }
 9855
 9856    pub async fn handle_restart_language_servers(
 9857        this: Entity<Self>,
 9858        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9859        mut cx: AsyncApp,
 9860    ) -> Result<proto::Ack> {
 9861        this.update(&mut cx, |lsp_store, cx| {
 9862            let buffers =
 9863                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9864            lsp_store.restart_language_servers_for_buffers(
 9865                buffers,
 9866                envelope
 9867                    .payload
 9868                    .only_servers
 9869                    .into_iter()
 9870                    .filter_map(|selector| {
 9871                        Some(match selector.selector? {
 9872                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9873                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9874                            }
 9875                            proto::language_server_selector::Selector::Name(name) => {
 9876                                LanguageServerSelector::Name(LanguageServerName(
 9877                                    SharedString::from(name),
 9878                                ))
 9879                            }
 9880                        })
 9881                    })
 9882                    .collect(),
 9883                cx,
 9884            );
 9885        })?;
 9886
 9887        Ok(proto::Ack {})
 9888    }
 9889
 9890    pub async fn handle_stop_language_servers(
 9891        lsp_store: Entity<Self>,
 9892        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9893        mut cx: AsyncApp,
 9894    ) -> Result<proto::Ack> {
 9895        lsp_store.update(&mut cx, |lsp_store, cx| {
 9896            if envelope.payload.all
 9897                && envelope.payload.also_servers.is_empty()
 9898                && envelope.payload.buffer_ids.is_empty()
 9899            {
 9900                lsp_store.stop_all_language_servers(cx);
 9901            } else {
 9902                let buffers =
 9903                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9904                lsp_store
 9905                    .stop_language_servers_for_buffers(
 9906                        buffers,
 9907                        envelope
 9908                            .payload
 9909                            .also_servers
 9910                            .into_iter()
 9911                            .filter_map(|selector| {
 9912                                Some(match selector.selector? {
 9913                                    proto::language_server_selector::Selector::ServerId(
 9914                                        server_id,
 9915                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9916                                        server_id,
 9917                                    )),
 9918                                    proto::language_server_selector::Selector::Name(name) => {
 9919                                        LanguageServerSelector::Name(LanguageServerName(
 9920                                            SharedString::from(name),
 9921                                        ))
 9922                                    }
 9923                                })
 9924                            })
 9925                            .collect(),
 9926                        cx,
 9927                    )
 9928                    .detach_and_log_err(cx);
 9929            }
 9930        })?;
 9931
 9932        Ok(proto::Ack {})
 9933    }
 9934
 9935    pub async fn handle_cancel_language_server_work(
 9936        this: Entity<Self>,
 9937        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9938        mut cx: AsyncApp,
 9939    ) -> Result<proto::Ack> {
 9940        this.update(&mut cx, |this, cx| {
 9941            if let Some(work) = envelope.payload.work {
 9942                match work {
 9943                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9944                        let buffers =
 9945                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9946                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9947                    }
 9948                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9949                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9950                        this.cancel_language_server_work(server_id, work.token, cx);
 9951                    }
 9952                }
 9953            }
 9954        })?;
 9955
 9956        Ok(proto::Ack {})
 9957    }
 9958
 9959    fn buffer_ids_to_buffers(
 9960        &mut self,
 9961        buffer_ids: impl Iterator<Item = u64>,
 9962        cx: &mut Context<Self>,
 9963    ) -> Vec<Entity<Buffer>> {
 9964        buffer_ids
 9965            .into_iter()
 9966            .flat_map(|buffer_id| {
 9967                self.buffer_store
 9968                    .read(cx)
 9969                    .get(BufferId::new(buffer_id).log_err()?)
 9970            })
 9971            .collect::<Vec<_>>()
 9972    }
 9973
 9974    async fn handle_apply_additional_edits_for_completion(
 9975        this: Entity<Self>,
 9976        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
 9977        mut cx: AsyncApp,
 9978    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
 9979        let (buffer, completion) = this.update(&mut cx, |this, cx| {
 9980            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9981            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9982            let completion = Self::deserialize_completion(
 9983                envelope.payload.completion.context("invalid completion")?,
 9984            )?;
 9985            anyhow::Ok((buffer, completion))
 9986        })??;
 9987
 9988        let apply_additional_edits = this.update(&mut cx, |this, cx| {
 9989            this.apply_additional_edits_for_completion(
 9990                buffer,
 9991                Rc::new(RefCell::new(Box::new([Completion {
 9992                    replace_range: completion.replace_range,
 9993                    new_text: completion.new_text,
 9994                    source: completion.source,
 9995                    documentation: None,
 9996                    label: CodeLabel {
 9997                        text: Default::default(),
 9998                        runs: Default::default(),
 9999                        filter_range: Default::default(),
10000                    },
10001                    insert_text_mode: None,
10002                    icon_path: None,
10003                    confirm: None,
10004                }]))),
10005                0,
10006                false,
10007                cx,
10008            )
10009        })?;
10010
10011        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10012            transaction: apply_additional_edits
10013                .await?
10014                .as_ref()
10015                .map(language::proto::serialize_transaction),
10016        })
10017    }
10018
10019    pub fn last_formatting_failure(&self) -> Option<&str> {
10020        self.last_formatting_failure.as_deref()
10021    }
10022
10023    pub fn reset_last_formatting_failure(&mut self) {
10024        self.last_formatting_failure = None;
10025    }
10026
10027    pub fn environment_for_buffer(
10028        &self,
10029        buffer: &Entity<Buffer>,
10030        cx: &mut Context<Self>,
10031    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10032        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10033            environment.update(cx, |env, cx| {
10034                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10035            })
10036        } else {
10037            Task::ready(None).shared()
10038        }
10039    }
10040
10041    pub fn format(
10042        &mut self,
10043        buffers: HashSet<Entity<Buffer>>,
10044        target: LspFormatTarget,
10045        push_to_history: bool,
10046        trigger: FormatTrigger,
10047        cx: &mut Context<Self>,
10048    ) -> Task<anyhow::Result<ProjectTransaction>> {
10049        let logger = zlog::scoped!("format");
10050        if let Some(_) = self.as_local() {
10051            zlog::trace!(logger => "Formatting locally");
10052            let logger = zlog::scoped!(logger => "local");
10053            let buffers = buffers
10054                .into_iter()
10055                .map(|buffer_handle| {
10056                    let buffer = buffer_handle.read(cx);
10057                    let buffer_abs_path = File::from_dyn(buffer.file())
10058                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10059
10060                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10061                })
10062                .collect::<Vec<_>>();
10063
10064            cx.spawn(async move |lsp_store, cx| {
10065                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10066
10067                for (handle, abs_path, id) in buffers {
10068                    let env = lsp_store
10069                        .update(cx, |lsp_store, cx| {
10070                            lsp_store.environment_for_buffer(&handle, cx)
10071                        })?
10072                        .await;
10073
10074                    let ranges = match &target {
10075                        LspFormatTarget::Buffers => None,
10076                        LspFormatTarget::Ranges(ranges) => {
10077                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10078                        }
10079                    };
10080
10081                    formattable_buffers.push(FormattableBuffer {
10082                        handle,
10083                        abs_path,
10084                        env,
10085                        ranges,
10086                    });
10087                }
10088                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10089
10090                let format_timer = zlog::time!(logger => "Formatting buffers");
10091                let result = LocalLspStore::format_locally(
10092                    lsp_store.clone(),
10093                    formattable_buffers,
10094                    push_to_history,
10095                    trigger,
10096                    logger,
10097                    cx,
10098                )
10099                .await;
10100                format_timer.end();
10101
10102                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10103
10104                lsp_store.update(cx, |lsp_store, _| {
10105                    lsp_store.update_last_formatting_failure(&result);
10106                })?;
10107
10108                result
10109            })
10110        } else if let Some((client, project_id)) = self.upstream_client() {
10111            zlog::trace!(logger => "Formatting remotely");
10112            let logger = zlog::scoped!(logger => "remote");
10113            // Don't support formatting ranges via remote
10114            match target {
10115                LspFormatTarget::Buffers => {}
10116                LspFormatTarget::Ranges(_) => {
10117                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10118                    return Task::ready(Ok(ProjectTransaction::default()));
10119                }
10120            }
10121
10122            let buffer_store = self.buffer_store();
10123            cx.spawn(async move |lsp_store, cx| {
10124                zlog::trace!(logger => "Sending remote format request");
10125                let request_timer = zlog::time!(logger => "remote format request");
10126                let result = client
10127                    .request(proto::FormatBuffers {
10128                        project_id,
10129                        trigger: trigger as i32,
10130                        buffer_ids: buffers
10131                            .iter()
10132                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10133                            .collect::<Result<_>>()?,
10134                    })
10135                    .await
10136                    .and_then(|result| result.transaction.context("missing transaction"));
10137                request_timer.end();
10138
10139                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10140
10141                lsp_store.update(cx, |lsp_store, _| {
10142                    lsp_store.update_last_formatting_failure(&result);
10143                })?;
10144
10145                let transaction_response = result?;
10146                let _timer = zlog::time!(logger => "deserializing project transaction");
10147                buffer_store
10148                    .update(cx, |buffer_store, cx| {
10149                        buffer_store.deserialize_project_transaction(
10150                            transaction_response,
10151                            push_to_history,
10152                            cx,
10153                        )
10154                    })?
10155                    .await
10156            })
10157        } else {
10158            zlog::trace!(logger => "Not formatting");
10159            Task::ready(Ok(ProjectTransaction::default()))
10160        }
10161    }
10162
10163    async fn handle_format_buffers(
10164        this: Entity<Self>,
10165        envelope: TypedEnvelope<proto::FormatBuffers>,
10166        mut cx: AsyncApp,
10167    ) -> Result<proto::FormatBuffersResponse> {
10168        let sender_id = envelope.original_sender_id().unwrap_or_default();
10169        let format = this.update(&mut cx, |this, cx| {
10170            let mut buffers = HashSet::default();
10171            for buffer_id in &envelope.payload.buffer_ids {
10172                let buffer_id = BufferId::new(*buffer_id)?;
10173                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10174            }
10175            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10176            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10177        })??;
10178
10179        let project_transaction = format.await?;
10180        let project_transaction = this.update(&mut cx, |this, cx| {
10181            this.buffer_store.update(cx, |buffer_store, cx| {
10182                buffer_store.serialize_project_transaction_for_peer(
10183                    project_transaction,
10184                    sender_id,
10185                    cx,
10186                )
10187            })
10188        })?;
10189        Ok(proto::FormatBuffersResponse {
10190            transaction: Some(project_transaction),
10191        })
10192    }
10193
10194    async fn handle_apply_code_action_kind(
10195        this: Entity<Self>,
10196        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10197        mut cx: AsyncApp,
10198    ) -> Result<proto::ApplyCodeActionKindResponse> {
10199        let sender_id = envelope.original_sender_id().unwrap_or_default();
10200        let format = this.update(&mut cx, |this, cx| {
10201            let mut buffers = HashSet::default();
10202            for buffer_id in &envelope.payload.buffer_ids {
10203                let buffer_id = BufferId::new(*buffer_id)?;
10204                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10205            }
10206            let kind = match envelope.payload.kind.as_str() {
10207                "" => CodeActionKind::EMPTY,
10208                "quickfix" => CodeActionKind::QUICKFIX,
10209                "refactor" => CodeActionKind::REFACTOR,
10210                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10211                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10212                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10213                "source" => CodeActionKind::SOURCE,
10214                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10215                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10216                _ => anyhow::bail!(
10217                    "Invalid code action kind {}",
10218                    envelope.payload.kind.as_str()
10219                ),
10220            };
10221            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10222        })??;
10223
10224        let project_transaction = format.await?;
10225        let project_transaction = this.update(&mut cx, |this, cx| {
10226            this.buffer_store.update(cx, |buffer_store, cx| {
10227                buffer_store.serialize_project_transaction_for_peer(
10228                    project_transaction,
10229                    sender_id,
10230                    cx,
10231                )
10232            })
10233        })?;
10234        Ok(proto::ApplyCodeActionKindResponse {
10235            transaction: Some(project_transaction),
10236        })
10237    }
10238
10239    async fn shutdown_language_server(
10240        server_state: Option<LanguageServerState>,
10241        name: LanguageServerName,
10242        cx: &mut AsyncApp,
10243    ) {
10244        let server = match server_state {
10245            Some(LanguageServerState::Starting { startup, .. }) => {
10246                let mut timer = cx
10247                    .background_executor()
10248                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10249                    .fuse();
10250
10251                select! {
10252                    server = startup.fuse() => server,
10253                    () = timer => {
10254                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10255                        None
10256                    },
10257                }
10258            }
10259
10260            Some(LanguageServerState::Running { server, .. }) => Some(server),
10261
10262            None => None,
10263        };
10264
10265        if let Some(server) = server
10266            && let Some(shutdown) = server.shutdown() {
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                        language_server_names_to_stop.retain(|name| {
10544                            let old_ids_count = language_servers_to_stop.len();
10545                            let all_language_servers_with_this_name = local
10546                                .language_server_ids
10547                                .iter()
10548                                .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10549                            language_servers_to_stop.extend(all_language_servers_with_this_name);
10550                            old_ids_count == language_servers_to_stop.len()
10551                        });
10552                    }
10553            });
10554        }
10555        for name in language_server_names_to_stop {
10556            language_servers_to_stop.extend(
10557                local
10558                    .language_server_ids
10559                    .iter()
10560                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10561            );
10562        }
10563
10564        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10565        let tasks = language_servers_to_stop
10566            .into_iter()
10567            .map(|server| self.stop_local_language_server(server, cx))
10568            .collect::<Vec<_>>();
10569
10570        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10571    }
10572
10573    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10574        let (worktree, relative_path) =
10575            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10576
10577        let project_path = ProjectPath {
10578            worktree_id: worktree.read(cx).id(),
10579            path: relative_path.into(),
10580        };
10581
10582        Some(
10583            self.buffer_store()
10584                .read(cx)
10585                .get_by_path(&project_path)?
10586                .read(cx),
10587        )
10588    }
10589
10590    #[cfg(any(test, feature = "test-support"))]
10591    pub fn update_diagnostics(
10592        &mut self,
10593        server_id: LanguageServerId,
10594        diagnostics: lsp::PublishDiagnosticsParams,
10595        result_id: Option<String>,
10596        source_kind: DiagnosticSourceKind,
10597        disk_based_sources: &[String],
10598        cx: &mut Context<Self>,
10599    ) -> Result<()> {
10600        self.merge_lsp_diagnostics(
10601            source_kind,
10602            vec![DocumentDiagnosticsUpdate {
10603                diagnostics,
10604                result_id,
10605                server_id,
10606                disk_based_sources: Cow::Borrowed(disk_based_sources),
10607            }],
10608            |_, _, _| false,
10609            cx,
10610        )
10611    }
10612
10613    pub fn merge_lsp_diagnostics(
10614        &mut self,
10615        source_kind: DiagnosticSourceKind,
10616        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10617        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10618        cx: &mut Context<Self>,
10619    ) -> Result<()> {
10620        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10621        let updates = lsp_diagnostics
10622            .into_iter()
10623            .filter_map(|update| {
10624                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10625                Some(DocumentDiagnosticsUpdate {
10626                    diagnostics: self.lsp_to_document_diagnostics(
10627                        abs_path,
10628                        source_kind,
10629                        update.server_id,
10630                        update.diagnostics,
10631                        &update.disk_based_sources,
10632                    ),
10633                    result_id: update.result_id,
10634                    server_id: update.server_id,
10635                    disk_based_sources: update.disk_based_sources,
10636                })
10637            })
10638            .collect();
10639        self.merge_diagnostic_entries(updates, merge, cx)?;
10640        Ok(())
10641    }
10642
10643    fn lsp_to_document_diagnostics(
10644        &mut self,
10645        document_abs_path: PathBuf,
10646        source_kind: DiagnosticSourceKind,
10647        server_id: LanguageServerId,
10648        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10649        disk_based_sources: &[String],
10650    ) -> DocumentDiagnostics {
10651        let mut diagnostics = Vec::default();
10652        let mut primary_diagnostic_group_ids = HashMap::default();
10653        let mut sources_by_group_id = HashMap::default();
10654        let mut supporting_diagnostics = HashMap::default();
10655
10656        let adapter = self.language_server_adapter_for_id(server_id);
10657
10658        // Ensure that primary diagnostics are always the most severe
10659        lsp_diagnostics
10660            .diagnostics
10661            .sort_by_key(|item| item.severity);
10662
10663        for diagnostic in &lsp_diagnostics.diagnostics {
10664            let source = diagnostic.source.as_ref();
10665            let range = range_from_lsp(diagnostic.range);
10666            let is_supporting = diagnostic
10667                .related_information
10668                .as_ref()
10669                .map_or(false, |infos| {
10670                    infos.iter().any(|info| {
10671                        primary_diagnostic_group_ids.contains_key(&(
10672                            source,
10673                            diagnostic.code.clone(),
10674                            range_from_lsp(info.location.range),
10675                        ))
10676                    })
10677                });
10678
10679            let is_unnecessary = diagnostic
10680                .tags
10681                .as_ref()
10682                .map_or(false, |tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10683
10684            let underline = self
10685                .language_server_adapter_for_id(server_id)
10686                .map_or(true, |adapter| adapter.underline_diagnostic(diagnostic));
10687
10688            if is_supporting {
10689                supporting_diagnostics.insert(
10690                    (source, diagnostic.code.clone(), range),
10691                    (diagnostic.severity, is_unnecessary),
10692                );
10693            } else {
10694                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10695                let is_disk_based =
10696                    source.map_or(false, |source| disk_based_sources.contains(source));
10697
10698                sources_by_group_id.insert(group_id, source);
10699                primary_diagnostic_group_ids
10700                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10701
10702                diagnostics.push(DiagnosticEntry {
10703                    range,
10704                    diagnostic: Diagnostic {
10705                        source: diagnostic.source.clone(),
10706                        source_kind,
10707                        code: diagnostic.code.clone(),
10708                        code_description: diagnostic
10709                            .code_description
10710                            .as_ref()
10711                            .and_then(|d| d.href.clone()),
10712                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10713                        markdown: adapter.as_ref().and_then(|adapter| {
10714                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10715                        }),
10716                        message: diagnostic.message.trim().to_string(),
10717                        group_id,
10718                        is_primary: true,
10719                        is_disk_based,
10720                        is_unnecessary,
10721                        underline,
10722                        data: diagnostic.data.clone(),
10723                    },
10724                });
10725                if let Some(infos) = &diagnostic.related_information {
10726                    for info in infos {
10727                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10728                            let range = range_from_lsp(info.location.range);
10729                            diagnostics.push(DiagnosticEntry {
10730                                range,
10731                                diagnostic: Diagnostic {
10732                                    source: diagnostic.source.clone(),
10733                                    source_kind,
10734                                    code: diagnostic.code.clone(),
10735                                    code_description: diagnostic
10736                                        .code_description
10737                                        .as_ref()
10738                                        .and_then(|d| d.href.clone()),
10739                                    severity: DiagnosticSeverity::INFORMATION,
10740                                    markdown: adapter.as_ref().and_then(|adapter| {
10741                                        adapter.diagnostic_message_to_markdown(&info.message)
10742                                    }),
10743                                    message: info.message.trim().to_string(),
10744                                    group_id,
10745                                    is_primary: false,
10746                                    is_disk_based,
10747                                    is_unnecessary: false,
10748                                    underline,
10749                                    data: diagnostic.data.clone(),
10750                                },
10751                            });
10752                        }
10753                    }
10754                }
10755            }
10756        }
10757
10758        for entry in &mut diagnostics {
10759            let diagnostic = &mut entry.diagnostic;
10760            if !diagnostic.is_primary {
10761                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10762                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10763                    source,
10764                    diagnostic.code.clone(),
10765                    entry.range.clone(),
10766                )) {
10767                    if let Some(severity) = severity {
10768                        diagnostic.severity = severity;
10769                    }
10770                    diagnostic.is_unnecessary = is_unnecessary;
10771                }
10772            }
10773        }
10774
10775        DocumentDiagnostics {
10776            diagnostics,
10777            document_abs_path,
10778            version: lsp_diagnostics.version,
10779        }
10780    }
10781
10782    fn insert_newly_running_language_server(
10783        &mut self,
10784        adapter: Arc<CachedLspAdapter>,
10785        language_server: Arc<LanguageServer>,
10786        server_id: LanguageServerId,
10787        key: LanguageServerSeed,
10788        workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
10789        cx: &mut Context<Self>,
10790    ) {
10791        let Some(local) = self.as_local_mut() else {
10792            return;
10793        };
10794        // If the language server for this key doesn't match the server id, don't store the
10795        // server. Which will cause it to be dropped, killing the process
10796        if local
10797            .language_server_ids
10798            .get(&key)
10799            .map(|state| state.id != server_id)
10800            .unwrap_or(false)
10801        {
10802            return;
10803        }
10804
10805        // Update language_servers collection with Running variant of LanguageServerState
10806        // indicating that the server is up and running and ready
10807        let workspace_folders = workspace_folders.lock().clone();
10808        language_server.set_workspace_folders(workspace_folders);
10809
10810        local.language_servers.insert(
10811            server_id,
10812            LanguageServerState::Running {
10813                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10814                    language_server.clone(),
10815                    cx,
10816                ),
10817                adapter: adapter.clone(),
10818                server: language_server.clone(),
10819                simulate_disk_based_diagnostics_completion: None,
10820            },
10821        );
10822        local
10823            .languages
10824            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10825        if let Some(file_ops_caps) = language_server
10826            .capabilities()
10827            .workspace
10828            .as_ref()
10829            .and_then(|ws| ws.file_operations.as_ref())
10830        {
10831            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10832            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10833            if did_rename_caps.or(will_rename_caps).is_some() {
10834                let watcher = RenamePathsWatchedForServer::default()
10835                    .with_did_rename_patterns(did_rename_caps)
10836                    .with_will_rename_patterns(will_rename_caps);
10837                local
10838                    .language_server_paths_watched_for_rename
10839                    .insert(server_id, watcher);
10840            }
10841        }
10842
10843        self.language_server_statuses.insert(
10844            server_id,
10845            LanguageServerStatus {
10846                name: language_server.name(),
10847                pending_work: Default::default(),
10848                has_pending_diagnostic_updates: false,
10849                progress_tokens: Default::default(),
10850            },
10851        );
10852
10853        cx.emit(LspStoreEvent::LanguageServerAdded(
10854            server_id,
10855            language_server.name(),
10856            Some(key.worktree_id),
10857        ));
10858        cx.emit(LspStoreEvent::RefreshInlayHints);
10859
10860        let server_capabilities = language_server.capabilities();
10861        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10862            downstream_client
10863                .send(proto::StartLanguageServer {
10864                    project_id: *project_id,
10865                    server: Some(proto::LanguageServer {
10866                        id: server_id.to_proto(),
10867                        name: language_server.name().to_string(),
10868                        worktree_id: Some(key.worktree_id.to_proto()),
10869                    }),
10870                    capabilities: serde_json::to_string(&server_capabilities)
10871                        .expect("serializing server LSP capabilities"),
10872                })
10873                .log_err();
10874        }
10875        self.lsp_server_capabilities
10876            .insert(server_id, server_capabilities);
10877
10878        // Tell the language server about every open buffer in the worktree that matches the language.
10879        // Also check for buffers in worktrees that reused this server
10880        let mut worktrees_using_server = vec![key.worktree_id];
10881        if let Some(local) = self.as_local() {
10882            // Find all worktrees that have this server in their language server tree
10883            for (worktree_id, servers) in &local.lsp_tree.instances {
10884                if *worktree_id != key.worktree_id {
10885                    for (_, server_map) in &servers.roots {
10886                        if server_map.contains_key(&key.name) {
10887                            worktrees_using_server.push(*worktree_id);
10888                        }
10889                    }
10890                }
10891            }
10892        }
10893
10894        let mut buffer_paths_registered = Vec::new();
10895        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10896            for buffer_handle in buffer_store.buffers() {
10897                let buffer = buffer_handle.read(cx);
10898                let file = match File::from_dyn(buffer.file()) {
10899                    Some(file) => file,
10900                    None => continue,
10901                };
10902                let language = match buffer.language() {
10903                    Some(language) => language,
10904                    None => continue,
10905                };
10906
10907                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10908                    || !self
10909                        .languages
10910                        .lsp_adapters(&language.name())
10911                        .iter()
10912                        .any(|a| a.name == key.name)
10913                {
10914                    continue;
10915                }
10916                // didOpen
10917                let file = match file.as_local() {
10918                    Some(file) => file,
10919                    None => continue,
10920                };
10921
10922                let local = self.as_local_mut().unwrap();
10923
10924                let buffer_id = buffer.remote_id();
10925                if local.registered_buffers.contains_key(&buffer_id) {
10926                    let versions = local
10927                        .buffer_snapshots
10928                        .entry(buffer_id)
10929                        .or_default()
10930                        .entry(server_id)
10931                        .and_modify(|_| {
10932                            assert!(
10933                            false,
10934                            "There should not be an existing snapshot for a newly inserted buffer"
10935                        )
10936                        })
10937                        .or_insert_with(|| {
10938                            vec![LspBufferSnapshot {
10939                                version: 0,
10940                                snapshot: buffer.text_snapshot(),
10941                            }]
10942                        });
10943
10944                    let snapshot = versions.last().unwrap();
10945                    let version = snapshot.version;
10946                    let initial_snapshot = &snapshot.snapshot;
10947                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
10948                    language_server.register_buffer(
10949                        uri,
10950                        adapter.language_id(&language.name()),
10951                        version,
10952                        initial_snapshot.text(),
10953                    );
10954                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10955                    local
10956                        .buffers_opened_in_servers
10957                        .entry(buffer_id)
10958                        .or_default()
10959                        .insert(server_id);
10960                }
10961                buffer_handle.update(cx, |buffer, cx| {
10962                    buffer.set_completion_triggers(
10963                        server_id,
10964                        language_server
10965                            .capabilities()
10966                            .completion_provider
10967                            .as_ref()
10968                            .and_then(|provider| {
10969                                provider
10970                                    .trigger_characters
10971                                    .as_ref()
10972                                    .map(|characters| characters.iter().cloned().collect())
10973                            })
10974                            .unwrap_or_default(),
10975                        cx,
10976                    )
10977                });
10978            }
10979        });
10980
10981        for (buffer_id, abs_path) in buffer_paths_registered {
10982            cx.emit(LspStoreEvent::LanguageServerUpdate {
10983                language_server_id: server_id,
10984                name: Some(adapter.name()),
10985                message: proto::update_language_server::Variant::RegisteredForBuffer(
10986                    proto::RegisteredForBuffer {
10987                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
10988                        buffer_id: buffer_id.to_proto(),
10989                    },
10990                ),
10991            });
10992        }
10993
10994        cx.notify();
10995    }
10996
10997    pub fn language_servers_running_disk_based_diagnostics(
10998        &self,
10999    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11000        self.language_server_statuses
11001            .iter()
11002            .filter_map(|(id, status)| {
11003                if status.has_pending_diagnostic_updates {
11004                    Some(*id)
11005                } else {
11006                    None
11007                }
11008            })
11009    }
11010
11011    pub(crate) fn cancel_language_server_work_for_buffers(
11012        &mut self,
11013        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11014        cx: &mut Context<Self>,
11015    ) {
11016        if let Some((client, project_id)) = self.upstream_client() {
11017            let request = client.request(proto::CancelLanguageServerWork {
11018                project_id,
11019                work: Some(proto::cancel_language_server_work::Work::Buffers(
11020                    proto::cancel_language_server_work::Buffers {
11021                        buffer_ids: buffers
11022                            .into_iter()
11023                            .map(|b| b.read(cx).remote_id().to_proto())
11024                            .collect(),
11025                    },
11026                )),
11027            });
11028            cx.background_spawn(request).detach_and_log_err(cx);
11029        } else if let Some(local) = self.as_local() {
11030            let servers = buffers
11031                .into_iter()
11032                .flat_map(|buffer| {
11033                    buffer.update(cx, |buffer, cx| {
11034                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11035                    })
11036                })
11037                .collect::<HashSet<_>>();
11038            for server_id in servers {
11039                self.cancel_language_server_work(server_id, None, cx);
11040            }
11041        }
11042    }
11043
11044    pub(crate) fn cancel_language_server_work(
11045        &mut self,
11046        server_id: LanguageServerId,
11047        token_to_cancel: Option<String>,
11048        cx: &mut Context<Self>,
11049    ) {
11050        if let Some(local) = self.as_local() {
11051            let status = self.language_server_statuses.get(&server_id);
11052            let server = local.language_servers.get(&server_id);
11053            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11054            {
11055                for (token, progress) in &status.pending_work {
11056                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11057                        && token != token_to_cancel {
11058                            continue;
11059                        }
11060                    if progress.is_cancellable {
11061                        server
11062                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11063                                &WorkDoneProgressCancelParams {
11064                                    token: lsp::NumberOrString::String(token.clone()),
11065                                },
11066                            )
11067                            .ok();
11068                    }
11069                }
11070            }
11071        } else if let Some((client, project_id)) = self.upstream_client() {
11072            let request = client.request(proto::CancelLanguageServerWork {
11073                project_id,
11074                work: Some(
11075                    proto::cancel_language_server_work::Work::LanguageServerWork(
11076                        proto::cancel_language_server_work::LanguageServerWork {
11077                            language_server_id: server_id.to_proto(),
11078                            token: token_to_cancel,
11079                        },
11080                    ),
11081                ),
11082            });
11083            cx.background_spawn(request).detach_and_log_err(cx);
11084        }
11085    }
11086
11087    fn register_supplementary_language_server(
11088        &mut self,
11089        id: LanguageServerId,
11090        name: LanguageServerName,
11091        server: Arc<LanguageServer>,
11092        cx: &mut Context<Self>,
11093    ) {
11094        if let Some(local) = self.as_local_mut() {
11095            local
11096                .supplementary_language_servers
11097                .insert(id, (name.clone(), server));
11098            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11099        }
11100    }
11101
11102    fn unregister_supplementary_language_server(
11103        &mut self,
11104        id: LanguageServerId,
11105        cx: &mut Context<Self>,
11106    ) {
11107        if let Some(local) = self.as_local_mut() {
11108            local.supplementary_language_servers.remove(&id);
11109            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11110        }
11111    }
11112
11113    pub(crate) fn supplementary_language_servers(
11114        &self,
11115    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11116        self.as_local().into_iter().flat_map(|local| {
11117            local
11118                .supplementary_language_servers
11119                .iter()
11120                .map(|(id, (name, _))| (*id, name.clone()))
11121        })
11122    }
11123
11124    pub fn language_server_adapter_for_id(
11125        &self,
11126        id: LanguageServerId,
11127    ) -> Option<Arc<CachedLspAdapter>> {
11128        self.as_local()
11129            .and_then(|local| local.language_servers.get(&id))
11130            .and_then(|language_server_state| match language_server_state {
11131                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11132                _ => None,
11133            })
11134    }
11135
11136    pub(super) fn update_local_worktree_language_servers(
11137        &mut self,
11138        worktree_handle: &Entity<Worktree>,
11139        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
11140        cx: &mut Context<Self>,
11141    ) {
11142        if changes.is_empty() {
11143            return;
11144        }
11145
11146        let Some(local) = self.as_local() else { return };
11147
11148        local.prettier_store.update(cx, |prettier_store, cx| {
11149            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11150        });
11151
11152        let worktree_id = worktree_handle.read(cx).id();
11153        let mut language_server_ids = local
11154            .language_server_ids
11155            .iter()
11156            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11157            .collect::<Vec<_>>();
11158        language_server_ids.sort();
11159        language_server_ids.dedup();
11160
11161        let abs_path = worktree_handle.read(cx).abs_path();
11162        for server_id in &language_server_ids {
11163            if let Some(LanguageServerState::Running { server, .. }) =
11164                local.language_servers.get(server_id)
11165                && let Some(watched_paths) = local
11166                    .language_server_watched_paths
11167                    .get(server_id)
11168                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11169                {
11170                    let params = lsp::DidChangeWatchedFilesParams {
11171                        changes: changes
11172                            .iter()
11173                            .filter_map(|(path, _, change)| {
11174                                if !watched_paths.is_match(path) {
11175                                    return None;
11176                                }
11177                                let typ = match change {
11178                                    PathChange::Loaded => return None,
11179                                    PathChange::Added => lsp::FileChangeType::CREATED,
11180                                    PathChange::Removed => lsp::FileChangeType::DELETED,
11181                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
11182                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11183                                };
11184                                Some(lsp::FileEvent {
11185                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
11186                                    typ,
11187                                })
11188                            })
11189                            .collect(),
11190                    };
11191                    if !params.changes.is_empty() {
11192                        server
11193                            .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
11194                            .ok();
11195                    }
11196                }
11197        }
11198        for (path, _, _) in changes {
11199            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
11200                && local.watched_manifest_filenames.contains(file_name)
11201            {
11202                self.request_workspace_config_refresh();
11203                break;
11204            }
11205        }
11206    }
11207
11208    pub fn wait_for_remote_buffer(
11209        &mut self,
11210        id: BufferId,
11211        cx: &mut Context<Self>,
11212    ) -> Task<Result<Entity<Buffer>>> {
11213        self.buffer_store.update(cx, |buffer_store, cx| {
11214            buffer_store.wait_for_remote_buffer(id, cx)
11215        })
11216    }
11217
11218    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11219        proto::Symbol {
11220            language_server_name: symbol.language_server_name.0.to_string(),
11221            source_worktree_id: symbol.source_worktree_id.to_proto(),
11222            language_server_id: symbol.source_language_server_id.to_proto(),
11223            worktree_id: symbol.path.worktree_id.to_proto(),
11224            path: symbol.path.path.as_ref().to_proto(),
11225            name: symbol.name.clone(),
11226            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11227            start: Some(proto::PointUtf16 {
11228                row: symbol.range.start.0.row,
11229                column: symbol.range.start.0.column,
11230            }),
11231            end: Some(proto::PointUtf16 {
11232                row: symbol.range.end.0.row,
11233                column: symbol.range.end.0.column,
11234            }),
11235            signature: symbol.signature.to_vec(),
11236        }
11237    }
11238
11239    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11240        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11241        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11242        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11243        let path = ProjectPath {
11244            worktree_id,
11245            path: Arc::<Path>::from_proto(serialized_symbol.path),
11246        };
11247
11248        let start = serialized_symbol.start.context("invalid start")?;
11249        let end = serialized_symbol.end.context("invalid end")?;
11250        Ok(CoreSymbol {
11251            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11252            source_worktree_id,
11253            source_language_server_id: LanguageServerId::from_proto(
11254                serialized_symbol.language_server_id,
11255            ),
11256            path,
11257            name: serialized_symbol.name,
11258            range: Unclipped(PointUtf16::new(start.row, start.column))
11259                ..Unclipped(PointUtf16::new(end.row, end.column)),
11260            kind,
11261            signature: serialized_symbol
11262                .signature
11263                .try_into()
11264                .map_err(|_| anyhow!("invalid signature"))?,
11265        })
11266    }
11267
11268    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11269        let mut serialized_completion = proto::Completion {
11270            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11271            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11272            new_text: completion.new_text.clone(),
11273            ..proto::Completion::default()
11274        };
11275        match &completion.source {
11276            CompletionSource::Lsp {
11277                insert_range,
11278                server_id,
11279                lsp_completion,
11280                lsp_defaults,
11281                resolved,
11282            } => {
11283                let (old_insert_start, old_insert_end) = insert_range
11284                    .as_ref()
11285                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11286                    .unzip();
11287
11288                serialized_completion.old_insert_start = old_insert_start;
11289                serialized_completion.old_insert_end = old_insert_end;
11290                serialized_completion.source = proto::completion::Source::Lsp as i32;
11291                serialized_completion.server_id = server_id.0 as u64;
11292                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11293                serialized_completion.lsp_defaults = lsp_defaults
11294                    .as_deref()
11295                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11296                serialized_completion.resolved = *resolved;
11297            }
11298            CompletionSource::BufferWord {
11299                word_range,
11300                resolved,
11301            } => {
11302                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11303                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11304                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11305                serialized_completion.resolved = *resolved;
11306            }
11307            CompletionSource::Custom => {
11308                serialized_completion.source = proto::completion::Source::Custom as i32;
11309                serialized_completion.resolved = true;
11310            }
11311            CompletionSource::Dap { sort_text } => {
11312                serialized_completion.source = proto::completion::Source::Dap as i32;
11313                serialized_completion.sort_text = Some(sort_text.clone());
11314            }
11315        }
11316
11317        serialized_completion
11318    }
11319
11320    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11321        let old_replace_start = completion
11322            .old_replace_start
11323            .and_then(deserialize_anchor)
11324            .context("invalid old start")?;
11325        let old_replace_end = completion
11326            .old_replace_end
11327            .and_then(deserialize_anchor)
11328            .context("invalid old end")?;
11329        let insert_range = {
11330            match completion.old_insert_start.zip(completion.old_insert_end) {
11331                Some((start, end)) => {
11332                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11333                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11334                    Some(start..end)
11335                }
11336                None => None,
11337            }
11338        };
11339        Ok(CoreCompletion {
11340            replace_range: old_replace_start..old_replace_end,
11341            new_text: completion.new_text,
11342            source: match proto::completion::Source::from_i32(completion.source) {
11343                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11344                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11345                    insert_range,
11346                    server_id: LanguageServerId::from_proto(completion.server_id),
11347                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11348                    lsp_defaults: completion
11349                        .lsp_defaults
11350                        .as_deref()
11351                        .map(serde_json::from_slice)
11352                        .transpose()?,
11353                    resolved: completion.resolved,
11354                },
11355                Some(proto::completion::Source::BufferWord) => {
11356                    let word_range = completion
11357                        .buffer_word_start
11358                        .and_then(deserialize_anchor)
11359                        .context("invalid buffer word start")?
11360                        ..completion
11361                            .buffer_word_end
11362                            .and_then(deserialize_anchor)
11363                            .context("invalid buffer word end")?;
11364                    CompletionSource::BufferWord {
11365                        word_range,
11366                        resolved: completion.resolved,
11367                    }
11368                }
11369                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11370                    sort_text: completion
11371                        .sort_text
11372                        .context("expected sort text to exist")?,
11373                },
11374                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11375            },
11376        })
11377    }
11378
11379    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11380        let (kind, lsp_action) = match &action.lsp_action {
11381            LspAction::Action(code_action) => (
11382                proto::code_action::Kind::Action as i32,
11383                serde_json::to_vec(code_action).unwrap(),
11384            ),
11385            LspAction::Command(command) => (
11386                proto::code_action::Kind::Command as i32,
11387                serde_json::to_vec(command).unwrap(),
11388            ),
11389            LspAction::CodeLens(code_lens) => (
11390                proto::code_action::Kind::CodeLens as i32,
11391                serde_json::to_vec(code_lens).unwrap(),
11392            ),
11393        };
11394
11395        proto::CodeAction {
11396            server_id: action.server_id.0 as u64,
11397            start: Some(serialize_anchor(&action.range.start)),
11398            end: Some(serialize_anchor(&action.range.end)),
11399            lsp_action,
11400            kind,
11401            resolved: action.resolved,
11402        }
11403    }
11404
11405    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11406        let start = action
11407            .start
11408            .and_then(deserialize_anchor)
11409            .context("invalid start")?;
11410        let end = action
11411            .end
11412            .and_then(deserialize_anchor)
11413            .context("invalid end")?;
11414        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11415            Some(proto::code_action::Kind::Action) => {
11416                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11417            }
11418            Some(proto::code_action::Kind::Command) => {
11419                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11420            }
11421            Some(proto::code_action::Kind::CodeLens) => {
11422                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11423            }
11424            None => anyhow::bail!("Unknown action kind {}", action.kind),
11425        };
11426        Ok(CodeAction {
11427            server_id: LanguageServerId(action.server_id as usize),
11428            range: start..end,
11429            resolved: action.resolved,
11430            lsp_action,
11431        })
11432    }
11433
11434    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11435        match &formatting_result {
11436            Ok(_) => self.last_formatting_failure = None,
11437            Err(error) => {
11438                let error_string = format!("{error:#}");
11439                log::error!("Formatting failed: {error_string}");
11440                self.last_formatting_failure
11441                    .replace(error_string.lines().join(" "));
11442            }
11443        }
11444    }
11445
11446    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11447        self.lsp_server_capabilities.remove(&for_server);
11448        for buffer_colors in self.lsp_document_colors.values_mut() {
11449            buffer_colors.colors.remove(&for_server);
11450            buffer_colors.cache_version += 1;
11451        }
11452        for buffer_lens in self.lsp_code_lens.values_mut() {
11453            buffer_lens.lens.remove(&for_server);
11454        }
11455        if let Some(local) = self.as_local_mut() {
11456            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11457            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11458                buffer_servers.remove(&for_server);
11459            }
11460        }
11461    }
11462
11463    pub fn result_id(
11464        &self,
11465        server_id: LanguageServerId,
11466        buffer_id: BufferId,
11467        cx: &App,
11468    ) -> Option<String> {
11469        let abs_path = self
11470            .buffer_store
11471            .read(cx)
11472            .get(buffer_id)
11473            .and_then(|b| File::from_dyn(b.read(cx).file()))
11474            .map(|f| f.abs_path(cx))?;
11475        self.as_local()?
11476            .buffer_pull_diagnostics_result_ids
11477            .get(&server_id)?
11478            .get(&abs_path)?
11479            .clone()
11480    }
11481
11482    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11483        let Some(local) = self.as_local() else {
11484            return HashMap::default();
11485        };
11486        local
11487            .buffer_pull_diagnostics_result_ids
11488            .get(&server_id)
11489            .into_iter()
11490            .flatten()
11491            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11492            .collect()
11493    }
11494
11495    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11496        if let Some(LanguageServerState::Running {
11497            workspace_refresh_task: Some(workspace_refresh_task),
11498            ..
11499        }) = self
11500            .as_local_mut()
11501            .and_then(|local| local.language_servers.get_mut(&server_id))
11502        {
11503            workspace_refresh_task.refresh_tx.try_send(()).ok();
11504        }
11505    }
11506
11507    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11508        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11509            return;
11510        };
11511        let Some(local) = self.as_local_mut() else {
11512            return;
11513        };
11514
11515        for server_id in buffer.update(cx, |buffer, cx| {
11516            local.language_server_ids_for_buffer(buffer, cx)
11517        }) {
11518            if let Some(LanguageServerState::Running {
11519                workspace_refresh_task: Some(workspace_refresh_task),
11520                ..
11521            }) = local.language_servers.get_mut(&server_id)
11522            {
11523                workspace_refresh_task.refresh_tx.try_send(()).ok();
11524            }
11525        }
11526    }
11527
11528    fn apply_workspace_diagnostic_report(
11529        &mut self,
11530        server_id: LanguageServerId,
11531        report: lsp::WorkspaceDiagnosticReportResult,
11532        cx: &mut Context<Self>,
11533    ) {
11534        let workspace_diagnostics =
11535            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11536        let mut unchanged_buffers = HashSet::default();
11537        let mut changed_buffers = HashSet::default();
11538        let workspace_diagnostics_updates = workspace_diagnostics
11539            .into_iter()
11540            .filter_map(
11541                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11542                    LspPullDiagnostics::Response {
11543                        server_id,
11544                        uri,
11545                        diagnostics,
11546                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11547                    LspPullDiagnostics::Default => None,
11548                },
11549            )
11550            .fold(
11551                HashMap::default(),
11552                |mut acc, (server_id, uri, diagnostics, version)| {
11553                    let (result_id, diagnostics) = match diagnostics {
11554                        PulledDiagnostics::Unchanged { result_id } => {
11555                            unchanged_buffers.insert(uri.clone());
11556                            (Some(result_id), Vec::new())
11557                        }
11558                        PulledDiagnostics::Changed {
11559                            result_id,
11560                            diagnostics,
11561                        } => {
11562                            changed_buffers.insert(uri.clone());
11563                            (result_id, diagnostics)
11564                        }
11565                    };
11566                    let disk_based_sources = Cow::Owned(
11567                        self.language_server_adapter_for_id(server_id)
11568                            .as_ref()
11569                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11570                            .unwrap_or(&[])
11571                            .to_vec(),
11572                    );
11573                    acc.entry(server_id)
11574                        .or_insert_with(Vec::new)
11575                        .push(DocumentDiagnosticsUpdate {
11576                            server_id,
11577                            diagnostics: lsp::PublishDiagnosticsParams {
11578                                uri,
11579                                diagnostics,
11580                                version,
11581                            },
11582                            result_id,
11583                            disk_based_sources,
11584                        });
11585                    acc
11586                },
11587            );
11588
11589        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11590            self.merge_lsp_diagnostics(
11591                DiagnosticSourceKind::Pulled,
11592                diagnostic_updates,
11593                |buffer, old_diagnostic, cx| {
11594                    File::from_dyn(buffer.file())
11595                        .and_then(|file| {
11596                            let abs_path = file.as_local()?.abs_path(cx);
11597                            lsp::Url::from_file_path(abs_path).ok()
11598                        })
11599                        .is_none_or(|buffer_uri| {
11600                            unchanged_buffers.contains(&buffer_uri)
11601                                || match old_diagnostic.source_kind {
11602                                    DiagnosticSourceKind::Pulled => {
11603                                        !changed_buffers.contains(&buffer_uri)
11604                                    }
11605                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11606                                        true
11607                                    }
11608                                }
11609                        })
11610                },
11611                cx,
11612            )
11613            .log_err();
11614        }
11615    }
11616
11617    fn register_server_capabilities(
11618        &mut self,
11619        server_id: LanguageServerId,
11620        params: lsp::RegistrationParams,
11621        cx: &mut Context<Self>,
11622    ) -> anyhow::Result<()> {
11623        let server = self
11624            .language_server_for_id(server_id)
11625            .with_context(|| format!("no server {server_id} found"))?;
11626        for reg in params.registrations {
11627            match reg.method.as_str() {
11628                "workspace/didChangeWatchedFiles" => {
11629                    if let Some(options) = reg.register_options {
11630                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11631                            let caps = serde_json::from_value(options)?;
11632                            local_lsp_store
11633                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11634                            true
11635                        } else {
11636                            false
11637                        };
11638                        if notify {
11639                            notify_server_capabilities_updated(&server, cx);
11640                        }
11641                    }
11642                }
11643                "workspace/didChangeConfiguration" => {
11644                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11645                }
11646                "workspace/symbol" => {
11647                    if let Some(options) = parse_register_capabilities(reg)? {
11648                        server.update_capabilities(|capabilities| {
11649                            capabilities.workspace_symbol_provider = Some(options);
11650                        });
11651                        notify_server_capabilities_updated(&server, cx);
11652                    }
11653                }
11654                "workspace/fileOperations" => {
11655                    if let Some(options) = reg.register_options {
11656                        let caps = serde_json::from_value(options)?;
11657                        server.update_capabilities(|capabilities| {
11658                            capabilities
11659                                .workspace
11660                                .get_or_insert_default()
11661                                .file_operations = Some(caps);
11662                        });
11663                        notify_server_capabilities_updated(&server, cx);
11664                    }
11665                }
11666                "workspace/executeCommand" => {
11667                    if let Some(options) = reg.register_options {
11668                        let options = serde_json::from_value(options)?;
11669                        server.update_capabilities(|capabilities| {
11670                            capabilities.execute_command_provider = Some(options);
11671                        });
11672                        notify_server_capabilities_updated(&server, cx);
11673                    }
11674                }
11675                "textDocument/rangeFormatting" => {
11676                    if let Some(options) = parse_register_capabilities(reg)? {
11677                        server.update_capabilities(|capabilities| {
11678                            capabilities.document_range_formatting_provider = Some(options);
11679                        });
11680                        notify_server_capabilities_updated(&server, cx);
11681                    }
11682                }
11683                "textDocument/onTypeFormatting" => {
11684                    if let Some(options) = reg
11685                        .register_options
11686                        .map(serde_json::from_value)
11687                        .transpose()?
11688                    {
11689                        server.update_capabilities(|capabilities| {
11690                            capabilities.document_on_type_formatting_provider = Some(options);
11691                        });
11692                        notify_server_capabilities_updated(&server, cx);
11693                    }
11694                }
11695                "textDocument/formatting" => {
11696                    if let Some(options) = parse_register_capabilities(reg)? {
11697                        server.update_capabilities(|capabilities| {
11698                            capabilities.document_formatting_provider = Some(options);
11699                        });
11700                        notify_server_capabilities_updated(&server, cx);
11701                    }
11702                }
11703                "textDocument/rename" => {
11704                    if let Some(options) = parse_register_capabilities(reg)? {
11705                        server.update_capabilities(|capabilities| {
11706                            capabilities.rename_provider = Some(options);
11707                        });
11708                        notify_server_capabilities_updated(&server, cx);
11709                    }
11710                }
11711                "textDocument/inlayHint" => {
11712                    if let Some(options) = parse_register_capabilities(reg)? {
11713                        server.update_capabilities(|capabilities| {
11714                            capabilities.inlay_hint_provider = Some(options);
11715                        });
11716                        notify_server_capabilities_updated(&server, cx);
11717                    }
11718                }
11719                "textDocument/documentSymbol" => {
11720                    if let Some(options) = parse_register_capabilities(reg)? {
11721                        server.update_capabilities(|capabilities| {
11722                            capabilities.document_symbol_provider = Some(options);
11723                        });
11724                        notify_server_capabilities_updated(&server, cx);
11725                    }
11726                }
11727                "textDocument/codeAction" => {
11728                    if let Some(options) = reg
11729                        .register_options
11730                        .map(serde_json::from_value)
11731                        .transpose()?
11732                    {
11733                        server.update_capabilities(|capabilities| {
11734                            capabilities.code_action_provider =
11735                                Some(lsp::CodeActionProviderCapability::Options(options));
11736                        });
11737                        notify_server_capabilities_updated(&server, cx);
11738                    }
11739                }
11740                "textDocument/definition" => {
11741                    if let Some(options) = parse_register_capabilities(reg)? {
11742                        server.update_capabilities(|capabilities| {
11743                            capabilities.definition_provider = Some(options);
11744                        });
11745                        notify_server_capabilities_updated(&server, cx);
11746                    }
11747                }
11748                "textDocument/completion" => {
11749                    if let Some(caps) = reg
11750                        .register_options
11751                        .map(serde_json::from_value)
11752                        .transpose()?
11753                    {
11754                        server.update_capabilities(|capabilities| {
11755                            capabilities.completion_provider = Some(caps);
11756                        });
11757                        notify_server_capabilities_updated(&server, cx);
11758                    }
11759                }
11760                "textDocument/hover" => {
11761                    if let Some(caps) = reg
11762                        .register_options
11763                        .map(serde_json::from_value)
11764                        .transpose()?
11765                    {
11766                        server.update_capabilities(|capabilities| {
11767                            capabilities.hover_provider = Some(caps);
11768                        });
11769                        notify_server_capabilities_updated(&server, cx);
11770                    }
11771                }
11772                "textDocument/signatureHelp" => {
11773                    if let Some(caps) = reg
11774                        .register_options
11775                        .map(serde_json::from_value)
11776                        .transpose()?
11777                    {
11778                        server.update_capabilities(|capabilities| {
11779                            capabilities.signature_help_provider = Some(caps);
11780                        });
11781                        notify_server_capabilities_updated(&server, cx);
11782                    }
11783                }
11784                "textDocument/didChange" => {
11785                    if let Some(sync_kind) = reg
11786                        .register_options
11787                        .and_then(|opts| opts.get("syncKind").cloned())
11788                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11789                        .transpose()?
11790                    {
11791                        server.update_capabilities(|capabilities| {
11792                            let mut sync_options =
11793                                Self::take_text_document_sync_options(capabilities);
11794                            sync_options.change = Some(sync_kind);
11795                            capabilities.text_document_sync =
11796                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11797                        });
11798                        notify_server_capabilities_updated(&server, cx);
11799                    }
11800                }
11801                "textDocument/didSave" => {
11802                    if let Some(save_options) = reg
11803                        .register_options
11804                        .and_then(|opts| opts.get("includeText").cloned())
11805                        .map(serde_json::from_value::<lsp::TextDocumentSyncSaveOptions>)
11806                        .transpose()?
11807                    {
11808                        server.update_capabilities(|capabilities| {
11809                            let mut sync_options =
11810                                Self::take_text_document_sync_options(capabilities);
11811                            sync_options.save = Some(save_options);
11812                            capabilities.text_document_sync =
11813                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11814                        });
11815                        notify_server_capabilities_updated(&server, cx);
11816                    }
11817                }
11818                "textDocument/codeLens" => {
11819                    if let Some(caps) = reg
11820                        .register_options
11821                        .map(serde_json::from_value)
11822                        .transpose()?
11823                    {
11824                        server.update_capabilities(|capabilities| {
11825                            capabilities.code_lens_provider = Some(caps);
11826                        });
11827                        notify_server_capabilities_updated(&server, cx);
11828                    }
11829                }
11830                "textDocument/diagnostic" => {
11831                    if let Some(caps) = reg
11832                        .register_options
11833                        .map(serde_json::from_value)
11834                        .transpose()?
11835                    {
11836                        server.update_capabilities(|capabilities| {
11837                            capabilities.diagnostic_provider = Some(caps);
11838                        });
11839                        notify_server_capabilities_updated(&server, cx);
11840                    }
11841                }
11842                "textDocument/colorProvider" => {
11843                    if let Some(caps) = reg
11844                        .register_options
11845                        .map(serde_json::from_value)
11846                        .transpose()?
11847                    {
11848                        server.update_capabilities(|capabilities| {
11849                            capabilities.color_provider = Some(caps);
11850                        });
11851                        notify_server_capabilities_updated(&server, cx);
11852                    }
11853                }
11854                _ => log::warn!("unhandled capability registration: {reg:?}"),
11855            }
11856        }
11857
11858        Ok(())
11859    }
11860
11861    fn unregister_server_capabilities(
11862        &mut self,
11863        server_id: LanguageServerId,
11864        params: lsp::UnregistrationParams,
11865        cx: &mut Context<Self>,
11866    ) -> anyhow::Result<()> {
11867        let server = self
11868            .language_server_for_id(server_id)
11869            .with_context(|| format!("no server {server_id} found"))?;
11870        for unreg in params.unregisterations.iter() {
11871            match unreg.method.as_str() {
11872                "workspace/didChangeWatchedFiles" => {
11873                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11874                        local_lsp_store
11875                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11876                        true
11877                    } else {
11878                        false
11879                    };
11880                    if notify {
11881                        notify_server_capabilities_updated(&server, cx);
11882                    }
11883                }
11884                "workspace/didChangeConfiguration" => {
11885                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11886                }
11887                "workspace/symbol" => {
11888                    server.update_capabilities(|capabilities| {
11889                        capabilities.workspace_symbol_provider = None
11890                    });
11891                    notify_server_capabilities_updated(&server, cx);
11892                }
11893                "workspace/fileOperations" => {
11894                    server.update_capabilities(|capabilities| {
11895                        capabilities
11896                            .workspace
11897                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11898                                workspace_folders: None,
11899                                file_operations: None,
11900                            })
11901                            .file_operations = None;
11902                    });
11903                    notify_server_capabilities_updated(&server, cx);
11904                }
11905                "workspace/executeCommand" => {
11906                    server.update_capabilities(|capabilities| {
11907                        capabilities.execute_command_provider = None;
11908                    });
11909                    notify_server_capabilities_updated(&server, cx);
11910                }
11911                "textDocument/rangeFormatting" => {
11912                    server.update_capabilities(|capabilities| {
11913                        capabilities.document_range_formatting_provider = None
11914                    });
11915                    notify_server_capabilities_updated(&server, cx);
11916                }
11917                "textDocument/onTypeFormatting" => {
11918                    server.update_capabilities(|capabilities| {
11919                        capabilities.document_on_type_formatting_provider = None;
11920                    });
11921                    notify_server_capabilities_updated(&server, cx);
11922                }
11923                "textDocument/formatting" => {
11924                    server.update_capabilities(|capabilities| {
11925                        capabilities.document_formatting_provider = None;
11926                    });
11927                    notify_server_capabilities_updated(&server, cx);
11928                }
11929                "textDocument/rename" => {
11930                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11931                    notify_server_capabilities_updated(&server, cx);
11932                }
11933                "textDocument/codeAction" => {
11934                    server.update_capabilities(|capabilities| {
11935                        capabilities.code_action_provider = None;
11936                    });
11937                    notify_server_capabilities_updated(&server, cx);
11938                }
11939                "textDocument/definition" => {
11940                    server.update_capabilities(|capabilities| {
11941                        capabilities.definition_provider = None;
11942                    });
11943                    notify_server_capabilities_updated(&server, cx);
11944                }
11945                "textDocument/completion" => {
11946                    server.update_capabilities(|capabilities| {
11947                        capabilities.completion_provider = None;
11948                    });
11949                    notify_server_capabilities_updated(&server, cx);
11950                }
11951                "textDocument/hover" => {
11952                    server.update_capabilities(|capabilities| {
11953                        capabilities.hover_provider = None;
11954                    });
11955                    notify_server_capabilities_updated(&server, cx);
11956                }
11957                "textDocument/signatureHelp" => {
11958                    server.update_capabilities(|capabilities| {
11959                        capabilities.signature_help_provider = None;
11960                    });
11961                    notify_server_capabilities_updated(&server, cx);
11962                }
11963                "textDocument/didChange" => {
11964                    server.update_capabilities(|capabilities| {
11965                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11966                        sync_options.change = None;
11967                        capabilities.text_document_sync =
11968                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11969                    });
11970                    notify_server_capabilities_updated(&server, cx);
11971                }
11972                "textDocument/didSave" => {
11973                    server.update_capabilities(|capabilities| {
11974                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11975                        sync_options.save = None;
11976                        capabilities.text_document_sync =
11977                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11978                    });
11979                    notify_server_capabilities_updated(&server, cx);
11980                }
11981                "textDocument/codeLens" => {
11982                    server.update_capabilities(|capabilities| {
11983                        capabilities.code_lens_provider = None;
11984                    });
11985                    notify_server_capabilities_updated(&server, cx);
11986                }
11987                "textDocument/diagnostic" => {
11988                    server.update_capabilities(|capabilities| {
11989                        capabilities.diagnostic_provider = None;
11990                    });
11991                    notify_server_capabilities_updated(&server, cx);
11992                }
11993                "textDocument/colorProvider" => {
11994                    server.update_capabilities(|capabilities| {
11995                        capabilities.color_provider = None;
11996                    });
11997                    notify_server_capabilities_updated(&server, cx);
11998                }
11999                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12000            }
12001        }
12002
12003        Ok(())
12004    }
12005
12006    fn take_text_document_sync_options(
12007        capabilities: &mut lsp::ServerCapabilities,
12008    ) -> lsp::TextDocumentSyncOptions {
12009        match capabilities.text_document_sync.take() {
12010            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12011            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12012                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12013                sync_options.change = Some(sync_kind);
12014                sync_options
12015            }
12016            None => lsp::TextDocumentSyncOptions::default(),
12017        }
12018    }
12019}
12020
12021// Registration with empty capabilities should be ignored.
12022// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/formatting.ts#L67-L70
12023fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12024    reg: lsp::Registration,
12025) -> anyhow::Result<Option<OneOf<bool, T>>> {
12026    Ok(reg
12027        .register_options
12028        .map(|options| serde_json::from_value::<T>(options))
12029        .transpose()?
12030        .map(OneOf::Right))
12031}
12032
12033fn subscribe_to_binary_statuses(
12034    languages: &Arc<LanguageRegistry>,
12035    cx: &mut Context<'_, LspStore>,
12036) -> Task<()> {
12037    let mut server_statuses = languages.language_server_binary_statuses();
12038    cx.spawn(async move |lsp_store, cx| {
12039        while let Some((server_name, binary_status)) = server_statuses.next().await {
12040            if lsp_store
12041                .update(cx, |_, cx| {
12042                    let mut message = None;
12043                    let binary_status = match binary_status {
12044                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12045                        BinaryStatus::CheckingForUpdate => {
12046                            proto::ServerBinaryStatus::CheckingForUpdate
12047                        }
12048                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12049                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12050                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12051                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12052                        BinaryStatus::Failed { error } => {
12053                            message = Some(error);
12054                            proto::ServerBinaryStatus::Failed
12055                        }
12056                    };
12057                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12058                        // Binary updates are about the binary that might not have any language server id at that point.
12059                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12060                        language_server_id: LanguageServerId(0),
12061                        name: Some(server_name),
12062                        message: proto::update_language_server::Variant::StatusUpdate(
12063                            proto::StatusUpdate {
12064                                message,
12065                                status: Some(proto::status_update::Status::Binary(
12066                                    binary_status as i32,
12067                                )),
12068                            },
12069                        ),
12070                    });
12071                })
12072                .is_err()
12073            {
12074                break;
12075            }
12076        }
12077    })
12078}
12079
12080fn lsp_workspace_diagnostics_refresh(
12081    server: Arc<LanguageServer>,
12082    cx: &mut Context<'_, LspStore>,
12083) -> Option<WorkspaceRefreshTask> {
12084    let identifier = match server.capabilities().diagnostic_provider? {
12085        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12086            if !diagnostic_options.workspace_diagnostics {
12087                return None;
12088            }
12089            diagnostic_options.identifier
12090        }
12091        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12092            let diagnostic_options = registration_options.diagnostic_options;
12093            if !diagnostic_options.workspace_diagnostics {
12094                return None;
12095            }
12096            diagnostic_options.identifier
12097        }
12098    };
12099
12100    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12101    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12102    refresh_tx.try_send(()).ok();
12103
12104    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12105        let mut attempts = 0;
12106        let max_attempts = 50;
12107        let mut requests = 0;
12108
12109        loop {
12110            let Some(()) = refresh_rx.recv().await else {
12111                return;
12112            };
12113
12114            'request: loop {
12115                requests += 1;
12116                if attempts > max_attempts {
12117                    log::error!(
12118                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12119                    );
12120                    return;
12121                }
12122                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12123                cx.background_executor()
12124                    .timer(Duration::from_millis(backoff_millis))
12125                    .await;
12126                attempts += 1;
12127
12128                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12129                    lsp_store
12130                        .all_result_ids(server.server_id())
12131                        .into_iter()
12132                        .filter_map(|(abs_path, result_id)| {
12133                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12134                            Some(lsp::PreviousResultId {
12135                                uri,
12136                                value: result_id,
12137                            })
12138                        })
12139                        .collect()
12140                }) else {
12141                    return;
12142                };
12143
12144                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12145
12146                progress_rx.try_recv().ok();
12147                let timer =
12148                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12149                let progress = pin!(progress_rx.recv().fuse());
12150                let response_result = server
12151                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12152                        lsp::WorkspaceDiagnosticParams {
12153                            previous_result_ids,
12154                            identifier: identifier.clone(),
12155                            work_done_progress_params: Default::default(),
12156                            partial_result_params: lsp::PartialResultParams {
12157                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12158                            },
12159                        },
12160                        select(timer, progress).then(|either| match either {
12161                            Either::Left((message, ..)) => ready(message).left_future(),
12162                            Either::Right(..) => pending::<String>().right_future(),
12163                        }),
12164                    )
12165                    .await;
12166
12167                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12168                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12169                match response_result {
12170                    ConnectionResult::Timeout => {
12171                        log::error!("Timeout during workspace diagnostics pull");
12172                        continue 'request;
12173                    }
12174                    ConnectionResult::ConnectionReset => {
12175                        log::error!("Server closed a workspace diagnostics pull request");
12176                        continue 'request;
12177                    }
12178                    ConnectionResult::Result(Err(e)) => {
12179                        log::error!("Error during workspace diagnostics pull: {e:#}");
12180                        break 'request;
12181                    }
12182                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12183                        attempts = 0;
12184                        if lsp_store
12185                            .update(cx, |lsp_store, cx| {
12186                                lsp_store.apply_workspace_diagnostic_report(
12187                                    server.server_id(),
12188                                    pulled_diagnostics,
12189                                    cx,
12190                                )
12191                            })
12192                            .is_err()
12193                        {
12194                            return;
12195                        }
12196                        break 'request;
12197                    }
12198                }
12199            }
12200        }
12201    });
12202
12203    Some(WorkspaceRefreshTask {
12204        refresh_tx,
12205        progress_tx,
12206        task: workspace_query_language_server,
12207    })
12208}
12209
12210fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12211    let CompletionSource::BufferWord {
12212        word_range,
12213        resolved,
12214    } = &mut completion.source
12215    else {
12216        return;
12217    };
12218    if *resolved {
12219        return;
12220    }
12221
12222    if completion.new_text
12223        != snapshot
12224            .text_for_range(word_range.clone())
12225            .collect::<String>()
12226    {
12227        return;
12228    }
12229
12230    let mut offset = 0;
12231    for chunk in snapshot.chunks(word_range.clone(), true) {
12232        let end_offset = offset + chunk.text.len();
12233        if let Some(highlight_id) = chunk.syntax_highlight_id {
12234            completion
12235                .label
12236                .runs
12237                .push((offset..end_offset, highlight_id));
12238        }
12239        offset = end_offset;
12240    }
12241    *resolved = true;
12242}
12243
12244impl EventEmitter<LspStoreEvent> for LspStore {}
12245
12246fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12247    hover
12248        .contents
12249        .retain(|hover_block| !hover_block.text.trim().is_empty());
12250    if hover.contents.is_empty() {
12251        None
12252    } else {
12253        Some(hover)
12254    }
12255}
12256
12257async fn populate_labels_for_completions(
12258    new_completions: Vec<CoreCompletion>,
12259    language: Option<Arc<Language>>,
12260    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12261) -> Vec<Completion> {
12262    let lsp_completions = new_completions
12263        .iter()
12264        .filter_map(|new_completion| {
12265            if let Some(lsp_completion) = new_completion.source.lsp_completion(true) {
12266                Some(lsp_completion.into_owned())
12267            } else {
12268                None
12269            }
12270        })
12271        .collect::<Vec<_>>();
12272
12273    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12274        lsp_adapter
12275            .labels_for_completions(&lsp_completions, language)
12276            .await
12277            .log_err()
12278            .unwrap_or_default()
12279    } else {
12280        Vec::new()
12281    }
12282    .into_iter()
12283    .fuse();
12284
12285    let mut completions = Vec::new();
12286    for completion in new_completions {
12287        match completion.source.lsp_completion(true) {
12288            Some(lsp_completion) => {
12289                let documentation = if let Some(docs) = lsp_completion.documentation.clone() {
12290                    Some(docs.into())
12291                } else {
12292                    None
12293                };
12294
12295                let mut label = labels.next().flatten().unwrap_or_else(|| {
12296                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12297                });
12298                ensure_uniform_list_compatible_label(&mut label);
12299                completions.push(Completion {
12300                    label,
12301                    documentation,
12302                    replace_range: completion.replace_range,
12303                    new_text: completion.new_text,
12304                    insert_text_mode: lsp_completion.insert_text_mode,
12305                    source: completion.source,
12306                    icon_path: None,
12307                    confirm: None,
12308                });
12309            }
12310            None => {
12311                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12312                ensure_uniform_list_compatible_label(&mut label);
12313                completions.push(Completion {
12314                    label,
12315                    documentation: None,
12316                    replace_range: completion.replace_range,
12317                    new_text: completion.new_text,
12318                    source: completion.source,
12319                    insert_text_mode: None,
12320                    icon_path: None,
12321                    confirm: None,
12322                });
12323            }
12324        }
12325    }
12326    completions
12327}
12328
12329#[derive(Debug)]
12330pub enum LanguageServerToQuery {
12331    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12332    FirstCapable,
12333    /// Query a specific language server.
12334    Other(LanguageServerId),
12335}
12336
12337#[derive(Default)]
12338struct RenamePathsWatchedForServer {
12339    did_rename: Vec<RenameActionPredicate>,
12340    will_rename: Vec<RenameActionPredicate>,
12341}
12342
12343impl RenamePathsWatchedForServer {
12344    fn with_did_rename_patterns(
12345        mut self,
12346        did_rename: Option<&FileOperationRegistrationOptions>,
12347    ) -> Self {
12348        if let Some(did_rename) = did_rename {
12349            self.did_rename = did_rename
12350                .filters
12351                .iter()
12352                .filter_map(|filter| filter.try_into().log_err())
12353                .collect();
12354        }
12355        self
12356    }
12357    fn with_will_rename_patterns(
12358        mut self,
12359        will_rename: Option<&FileOperationRegistrationOptions>,
12360    ) -> Self {
12361        if let Some(will_rename) = will_rename {
12362            self.will_rename = will_rename
12363                .filters
12364                .iter()
12365                .filter_map(|filter| filter.try_into().log_err())
12366                .collect();
12367        }
12368        self
12369    }
12370
12371    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12372        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12373    }
12374    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12375        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12376    }
12377}
12378
12379impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12380    type Error = globset::Error;
12381    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12382        Ok(Self {
12383            kind: ops.pattern.matches.clone(),
12384            glob: GlobBuilder::new(&ops.pattern.glob)
12385                .case_insensitive(
12386                    ops.pattern
12387                        .options
12388                        .as_ref()
12389                        .map_or(false, |ops| ops.ignore_case.unwrap_or(false)),
12390                )
12391                .build()?
12392                .compile_matcher(),
12393        })
12394    }
12395}
12396struct RenameActionPredicate {
12397    glob: GlobMatcher,
12398    kind: Option<FileOperationPatternKind>,
12399}
12400
12401impl RenameActionPredicate {
12402    // Returns true if language server should be notified
12403    fn eval(&self, path: &str, is_dir: bool) -> bool {
12404        self.kind.as_ref().map_or(true, |kind| {
12405            let expected_kind = if is_dir {
12406                FileOperationPatternKind::Folder
12407            } else {
12408                FileOperationPatternKind::File
12409            };
12410            kind == &expected_kind
12411        }) && self.glob.is_match(path)
12412    }
12413}
12414
12415#[derive(Default)]
12416struct LanguageServerWatchedPaths {
12417    worktree_paths: HashMap<WorktreeId, GlobSet>,
12418    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12419}
12420
12421#[derive(Default)]
12422struct LanguageServerWatchedPathsBuilder {
12423    worktree_paths: HashMap<WorktreeId, GlobSet>,
12424    abs_paths: HashMap<Arc<Path>, GlobSet>,
12425}
12426
12427impl LanguageServerWatchedPathsBuilder {
12428    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12429        self.worktree_paths.insert(worktree_id, glob_set);
12430    }
12431    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12432        self.abs_paths.insert(path, glob_set);
12433    }
12434    fn build(
12435        self,
12436        fs: Arc<dyn Fs>,
12437        language_server_id: LanguageServerId,
12438        cx: &mut Context<LspStore>,
12439    ) -> LanguageServerWatchedPaths {
12440        let project = cx.weak_entity();
12441
12442        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12443        let abs_paths = self
12444            .abs_paths
12445            .into_iter()
12446            .map(|(abs_path, globset)| {
12447                let task = cx.spawn({
12448                    let abs_path = abs_path.clone();
12449                    let fs = fs.clone();
12450
12451                    let lsp_store = project.clone();
12452                    async move |_, cx| {
12453                        maybe!(async move {
12454                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12455                            while let Some(update) = push_updates.0.next().await {
12456                                let action = lsp_store
12457                                    .update(cx, |this, _| {
12458                                        let Some(local) = this.as_local() else {
12459                                            return ControlFlow::Break(());
12460                                        };
12461                                        let Some(watcher) = local
12462                                            .language_server_watched_paths
12463                                            .get(&language_server_id)
12464                                        else {
12465                                            return ControlFlow::Break(());
12466                                        };
12467                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12468                                            "Watched abs path is not registered with a watcher",
12469                                        );
12470                                        let matching_entries = update
12471                                            .into_iter()
12472                                            .filter(|event| globs.is_match(&event.path))
12473                                            .collect::<Vec<_>>();
12474                                        this.lsp_notify_abs_paths_changed(
12475                                            language_server_id,
12476                                            matching_entries,
12477                                        );
12478                                        ControlFlow::Continue(())
12479                                    })
12480                                    .ok()?;
12481
12482                                if action.is_break() {
12483                                    break;
12484                                }
12485                            }
12486                            Some(())
12487                        })
12488                        .await;
12489                    }
12490                });
12491                (abs_path, (globset, task))
12492            })
12493            .collect();
12494        LanguageServerWatchedPaths {
12495            worktree_paths: self.worktree_paths,
12496            abs_paths,
12497        }
12498    }
12499}
12500
12501struct LspBufferSnapshot {
12502    version: i32,
12503    snapshot: TextBufferSnapshot,
12504}
12505
12506/// A prompt requested by LSP server.
12507#[derive(Clone, Debug)]
12508pub struct LanguageServerPromptRequest {
12509    pub level: PromptLevel,
12510    pub message: String,
12511    pub actions: Vec<MessageActionItem>,
12512    pub lsp_name: String,
12513    pub(crate) response_channel: Sender<MessageActionItem>,
12514}
12515
12516impl LanguageServerPromptRequest {
12517    pub async fn respond(self, index: usize) -> Option<()> {
12518        if let Some(response) = self.actions.into_iter().nth(index) {
12519            self.response_channel.send(response).await.ok()
12520        } else {
12521            None
12522        }
12523    }
12524}
12525impl PartialEq for LanguageServerPromptRequest {
12526    fn eq(&self, other: &Self) -> bool {
12527        self.message == other.message && self.actions == other.actions
12528    }
12529}
12530
12531#[derive(Clone, Debug, PartialEq)]
12532pub enum LanguageServerLogType {
12533    Log(MessageType),
12534    Trace(Option<String>),
12535}
12536
12537impl LanguageServerLogType {
12538    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12539        match self {
12540            Self::Log(log_type) => {
12541                let message_type = match *log_type {
12542                    MessageType::ERROR => 1,
12543                    MessageType::WARNING => 2,
12544                    MessageType::INFO => 3,
12545                    MessageType::LOG => 4,
12546                    other => {
12547                        log::warn!("Unknown lsp log message type: {:?}", other);
12548                        4
12549                    }
12550                };
12551                proto::language_server_log::LogType::LogMessageType(message_type)
12552            }
12553            Self::Trace(message) => {
12554                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
12555                    message: message.clone(),
12556                })
12557            }
12558        }
12559    }
12560
12561    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12562        match log_type {
12563            proto::language_server_log::LogType::LogMessageType(message_type) => {
12564                Self::Log(match message_type {
12565                    1 => MessageType::ERROR,
12566                    2 => MessageType::WARNING,
12567                    3 => MessageType::INFO,
12568                    4 => MessageType::LOG,
12569                    _ => MessageType::LOG,
12570                })
12571            }
12572            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
12573        }
12574    }
12575}
12576
12577pub struct WorkspaceRefreshTask {
12578    refresh_tx: mpsc::Sender<()>,
12579    progress_tx: mpsc::Sender<()>,
12580    #[allow(dead_code)]
12581    task: Task<()>,
12582}
12583
12584pub enum LanguageServerState {
12585    Starting {
12586        startup: Task<Option<Arc<LanguageServer>>>,
12587        /// List of language servers that will be added to the workspace once it's initialization completes.
12588        pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
12589    },
12590
12591    Running {
12592        adapter: Arc<CachedLspAdapter>,
12593        server: Arc<LanguageServer>,
12594        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12595        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12596    },
12597}
12598
12599impl LanguageServerState {
12600    fn add_workspace_folder(&self, uri: Url) {
12601        match self {
12602            LanguageServerState::Starting {
12603                pending_workspace_folders,
12604                ..
12605            } => {
12606                pending_workspace_folders.lock().insert(uri);
12607            }
12608            LanguageServerState::Running { server, .. } => {
12609                server.add_workspace_folder(uri);
12610            }
12611        }
12612    }
12613    fn _remove_workspace_folder(&self, uri: Url) {
12614        match self {
12615            LanguageServerState::Starting {
12616                pending_workspace_folders,
12617                ..
12618            } => {
12619                pending_workspace_folders.lock().remove(&uri);
12620            }
12621            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12622        }
12623    }
12624}
12625
12626impl std::fmt::Debug for LanguageServerState {
12627    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12628        match self {
12629            LanguageServerState::Starting { .. } => {
12630                f.debug_struct("LanguageServerState::Starting").finish()
12631            }
12632            LanguageServerState::Running { .. } => {
12633                f.debug_struct("LanguageServerState::Running").finish()
12634            }
12635        }
12636    }
12637}
12638
12639#[derive(Clone, Debug, Serialize)]
12640pub struct LanguageServerProgress {
12641    pub is_disk_based_diagnostics_progress: bool,
12642    pub is_cancellable: bool,
12643    pub title: Option<String>,
12644    pub message: Option<String>,
12645    pub percentage: Option<usize>,
12646    #[serde(skip_serializing)]
12647    pub last_update_at: Instant,
12648}
12649
12650#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12651pub struct DiagnosticSummary {
12652    pub error_count: usize,
12653    pub warning_count: usize,
12654}
12655
12656impl DiagnosticSummary {
12657    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12658        let mut this = Self {
12659            error_count: 0,
12660            warning_count: 0,
12661        };
12662
12663        for entry in diagnostics {
12664            if entry.diagnostic.is_primary {
12665                match entry.diagnostic.severity {
12666                    DiagnosticSeverity::ERROR => this.error_count += 1,
12667                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12668                    _ => {}
12669                }
12670            }
12671        }
12672
12673        this
12674    }
12675
12676    pub fn is_empty(&self) -> bool {
12677        self.error_count == 0 && self.warning_count == 0
12678    }
12679
12680    pub fn to_proto(
12681        &self,
12682        language_server_id: LanguageServerId,
12683        path: &Path,
12684    ) -> proto::DiagnosticSummary {
12685        proto::DiagnosticSummary {
12686            path: path.to_proto(),
12687            language_server_id: language_server_id.0 as u64,
12688            error_count: self.error_count as u32,
12689            warning_count: self.warning_count as u32,
12690        }
12691    }
12692}
12693
12694#[derive(Clone, Debug)]
12695pub enum CompletionDocumentation {
12696    /// There is no documentation for this completion.
12697    Undocumented,
12698    /// A single line of documentation.
12699    SingleLine(SharedString),
12700    /// Multiple lines of plain text documentation.
12701    MultiLinePlainText(SharedString),
12702    /// Markdown documentation.
12703    MultiLineMarkdown(SharedString),
12704    /// Both single line and multiple lines of plain text documentation.
12705    SingleLineAndMultiLinePlainText {
12706        single_line: SharedString,
12707        plain_text: Option<SharedString>,
12708    },
12709}
12710
12711impl From<lsp::Documentation> for CompletionDocumentation {
12712    fn from(docs: lsp::Documentation) -> Self {
12713        match docs {
12714            lsp::Documentation::String(text) => {
12715                if text.lines().count() <= 1 {
12716                    CompletionDocumentation::SingleLine(text.into())
12717                } else {
12718                    CompletionDocumentation::MultiLinePlainText(text.into())
12719                }
12720            }
12721
12722            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12723                lsp::MarkupKind::PlainText => {
12724                    if value.lines().count() <= 1 {
12725                        CompletionDocumentation::SingleLine(value.into())
12726                    } else {
12727                        CompletionDocumentation::MultiLinePlainText(value.into())
12728                    }
12729                }
12730
12731                lsp::MarkupKind::Markdown => {
12732                    CompletionDocumentation::MultiLineMarkdown(value.into())
12733                }
12734            },
12735        }
12736    }
12737}
12738
12739fn glob_literal_prefix(glob: &Path) -> PathBuf {
12740    glob.components()
12741        .take_while(|component| match component {
12742            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12743            _ => true,
12744        })
12745        .collect()
12746}
12747
12748pub struct SshLspAdapter {
12749    name: LanguageServerName,
12750    binary: LanguageServerBinary,
12751    initialization_options: Option<String>,
12752    code_action_kinds: Option<Vec<CodeActionKind>>,
12753}
12754
12755impl SshLspAdapter {
12756    pub fn new(
12757        name: LanguageServerName,
12758        binary: LanguageServerBinary,
12759        initialization_options: Option<String>,
12760        code_action_kinds: Option<String>,
12761    ) -> Self {
12762        Self {
12763            name,
12764            binary,
12765            initialization_options,
12766            code_action_kinds: code_action_kinds
12767                .as_ref()
12768                .and_then(|c| serde_json::from_str(c).ok()),
12769        }
12770    }
12771}
12772
12773#[async_trait(?Send)]
12774impl LspAdapter for SshLspAdapter {
12775    fn name(&self) -> LanguageServerName {
12776        self.name.clone()
12777    }
12778
12779    async fn initialization_options(
12780        self: Arc<Self>,
12781        _: &dyn Fs,
12782        _: &Arc<dyn LspAdapterDelegate>,
12783    ) -> Result<Option<serde_json::Value>> {
12784        let Some(options) = &self.initialization_options else {
12785            return Ok(None);
12786        };
12787        let result = serde_json::from_str(options)?;
12788        Ok(result)
12789    }
12790
12791    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12792        self.code_action_kinds.clone()
12793    }
12794
12795    async fn check_if_user_installed(
12796        &self,
12797        _: &dyn LspAdapterDelegate,
12798        _: Option<Toolchain>,
12799        _: &AsyncApp,
12800    ) -> Option<LanguageServerBinary> {
12801        Some(self.binary.clone())
12802    }
12803
12804    async fn cached_server_binary(
12805        &self,
12806        _: PathBuf,
12807        _: &dyn LspAdapterDelegate,
12808    ) -> Option<LanguageServerBinary> {
12809        None
12810    }
12811
12812    async fn fetch_latest_server_version(
12813        &self,
12814        _: &dyn LspAdapterDelegate,
12815    ) -> Result<Box<dyn 'static + Send + Any>> {
12816        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12817    }
12818
12819    async fn fetch_server_binary(
12820        &self,
12821        _: Box<dyn 'static + Send + Any>,
12822        _: PathBuf,
12823        _: &dyn LspAdapterDelegate,
12824    ) -> Result<LanguageServerBinary> {
12825        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12826    }
12827}
12828
12829pub fn language_server_settings<'a>(
12830    delegate: &'a dyn LspAdapterDelegate,
12831    language: &LanguageServerName,
12832    cx: &'a App,
12833) -> Option<&'a LspSettings> {
12834    language_server_settings_for(
12835        SettingsLocation {
12836            worktree_id: delegate.worktree_id(),
12837            path: delegate.worktree_root_path(),
12838        },
12839        language,
12840        cx,
12841    )
12842}
12843
12844pub(crate) fn language_server_settings_for<'a>(
12845    location: SettingsLocation<'a>,
12846    language: &LanguageServerName,
12847    cx: &'a App,
12848) -> Option<&'a LspSettings> {
12849    ProjectSettings::get(Some(location), cx).lsp.get(language)
12850}
12851
12852pub struct LocalLspAdapterDelegate {
12853    lsp_store: WeakEntity<LspStore>,
12854    worktree: worktree::Snapshot,
12855    fs: Arc<dyn Fs>,
12856    http_client: Arc<dyn HttpClient>,
12857    language_registry: Arc<LanguageRegistry>,
12858    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12859}
12860
12861impl LocalLspAdapterDelegate {
12862    pub fn new(
12863        language_registry: Arc<LanguageRegistry>,
12864        environment: &Entity<ProjectEnvironment>,
12865        lsp_store: WeakEntity<LspStore>,
12866        worktree: &Entity<Worktree>,
12867        http_client: Arc<dyn HttpClient>,
12868        fs: Arc<dyn Fs>,
12869        cx: &mut App,
12870    ) -> Arc<Self> {
12871        let load_shell_env_task = environment.update(cx, |env, cx| {
12872            env.get_worktree_environment(worktree.clone(), cx)
12873        });
12874
12875        Arc::new(Self {
12876            lsp_store,
12877            worktree: worktree.read(cx).snapshot(),
12878            fs,
12879            http_client,
12880            language_registry,
12881            load_shell_env_task,
12882        })
12883    }
12884
12885    fn from_local_lsp(
12886        local: &LocalLspStore,
12887        worktree: &Entity<Worktree>,
12888        cx: &mut App,
12889    ) -> Arc<Self> {
12890        Self::new(
12891            local.languages.clone(),
12892            &local.environment,
12893            local.weak.clone(),
12894            worktree,
12895            local.http_client.clone(),
12896            local.fs.clone(),
12897            cx,
12898        )
12899    }
12900}
12901
12902#[async_trait]
12903impl LspAdapterDelegate for LocalLspAdapterDelegate {
12904    fn show_notification(&self, message: &str, cx: &mut App) {
12905        self.lsp_store
12906            .update(cx, |_, cx| {
12907                cx.emit(LspStoreEvent::Notification(message.to_owned()))
12908            })
12909            .ok();
12910    }
12911
12912    fn http_client(&self) -> Arc<dyn HttpClient> {
12913        self.http_client.clone()
12914    }
12915
12916    fn worktree_id(&self) -> WorktreeId {
12917        self.worktree.id()
12918    }
12919
12920    fn worktree_root_path(&self) -> &Path {
12921        self.worktree.abs_path().as_ref()
12922    }
12923
12924    async fn shell_env(&self) -> HashMap<String, String> {
12925        let task = self.load_shell_env_task.clone();
12926        task.await.unwrap_or_default()
12927    }
12928
12929    async fn npm_package_installed_version(
12930        &self,
12931        package_name: &str,
12932    ) -> Result<Option<(PathBuf, String)>> {
12933        let local_package_directory = self.worktree_root_path();
12934        let node_modules_directory = local_package_directory.join("node_modules");
12935
12936        if let Some(version) =
12937            read_package_installed_version(node_modules_directory.clone(), package_name).await?
12938        {
12939            return Ok(Some((node_modules_directory, version)));
12940        }
12941        let Some(npm) = self.which("npm".as_ref()).await else {
12942            log::warn!(
12943                "Failed to find npm executable for {:?}",
12944                local_package_directory
12945            );
12946            return Ok(None);
12947        };
12948
12949        let env = self.shell_env().await;
12950        let output = util::command::new_smol_command(&npm)
12951            .args(["root", "-g"])
12952            .envs(env)
12953            .current_dir(local_package_directory)
12954            .output()
12955            .await?;
12956        let global_node_modules =
12957            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
12958
12959        if let Some(version) =
12960            read_package_installed_version(global_node_modules.clone(), package_name).await?
12961        {
12962            return Ok(Some((global_node_modules, version)));
12963        }
12964        return Ok(None);
12965    }
12966
12967    #[cfg(not(target_os = "windows"))]
12968    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12969        let worktree_abs_path = self.worktree.abs_path();
12970        let shell_path = self.shell_env().await.get("PATH").cloned();
12971        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
12972    }
12973
12974    #[cfg(target_os = "windows")]
12975    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12976        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
12977        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
12978        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
12979        which::which(command).ok()
12980    }
12981
12982    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
12983        let working_dir = self.worktree_root_path();
12984        let output = util::command::new_smol_command(&command.path)
12985            .args(command.arguments)
12986            .envs(command.env.clone().unwrap_or_default())
12987            .current_dir(working_dir)
12988            .output()
12989            .await?;
12990
12991        anyhow::ensure!(
12992            output.status.success(),
12993            "{}, stdout: {:?}, stderr: {:?}",
12994            output.status,
12995            String::from_utf8_lossy(&output.stdout),
12996            String::from_utf8_lossy(&output.stderr)
12997        );
12998        Ok(())
12999    }
13000
13001    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13002        self.language_registry
13003            .update_lsp_binary_status(server_name, status);
13004    }
13005
13006    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13007        self.language_registry
13008            .all_lsp_adapters()
13009            .into_iter()
13010            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13011            .collect()
13012    }
13013
13014    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13015        let dir = self.language_registry.language_server_download_dir(name)?;
13016
13017        if !dir.exists() {
13018            smol::fs::create_dir_all(&dir)
13019                .await
13020                .context("failed to create container directory")
13021                .log_err()?;
13022        }
13023
13024        Some(dir)
13025    }
13026
13027    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
13028        let entry = self
13029            .worktree
13030            .entry_for_path(&path)
13031            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13032        let abs_path = self
13033            .worktree
13034            .absolutize(&entry.path)
13035            .with_context(|| format!("cannot absolutize path {path:?}"))?;
13036
13037        self.fs.load(&abs_path).await
13038    }
13039}
13040
13041async fn populate_labels_for_symbols(
13042    symbols: Vec<CoreSymbol>,
13043    language_registry: &Arc<LanguageRegistry>,
13044    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13045    output: &mut Vec<Symbol>,
13046) {
13047    #[allow(clippy::mutable_key_type)]
13048    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13049
13050    let mut unknown_paths = BTreeSet::new();
13051    for symbol in symbols {
13052        let language = language_registry
13053            .language_for_file_path(&symbol.path.path)
13054            .await
13055            .ok()
13056            .or_else(|| {
13057                unknown_paths.insert(symbol.path.path.clone());
13058                None
13059            });
13060        symbols_by_language
13061            .entry(language)
13062            .or_default()
13063            .push(symbol);
13064    }
13065
13066    for unknown_path in unknown_paths {
13067        log::info!(
13068            "no language found for symbol path {}",
13069            unknown_path.display()
13070        );
13071    }
13072
13073    let mut label_params = Vec::new();
13074    for (language, mut symbols) in symbols_by_language {
13075        label_params.clear();
13076        label_params.extend(
13077            symbols
13078                .iter_mut()
13079                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13080        );
13081
13082        let mut labels = Vec::new();
13083        if let Some(language) = language {
13084            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13085                language_registry
13086                    .lsp_adapters(&language.name())
13087                    .first()
13088                    .cloned()
13089            });
13090            if let Some(lsp_adapter) = lsp_adapter {
13091                labels = lsp_adapter
13092                    .labels_for_symbols(&label_params, &language)
13093                    .await
13094                    .log_err()
13095                    .unwrap_or_default();
13096            }
13097        }
13098
13099        for ((symbol, (name, _)), label) in symbols
13100            .into_iter()
13101            .zip(label_params.drain(..))
13102            .zip(labels.into_iter().chain(iter::repeat(None)))
13103        {
13104            output.push(Symbol {
13105                language_server_name: symbol.language_server_name,
13106                source_worktree_id: symbol.source_worktree_id,
13107                source_language_server_id: symbol.source_language_server_id,
13108                path: symbol.path,
13109                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13110                name,
13111                kind: symbol.kind,
13112                range: symbol.range,
13113                signature: symbol.signature,
13114            });
13115        }
13116    }
13117}
13118
13119fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13120    match server.capabilities().text_document_sync.as_ref()? {
13121        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13122            // Server wants didSave but didn't specify includeText.
13123            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13124            // Server doesn't want didSave at all.
13125            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13126            // Server provided SaveOptions.
13127            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13128                Some(save_options.include_text.unwrap_or(false))
13129            }
13130        },
13131        // We do not have any save info. Kind affects didChange only.
13132        lsp::TextDocumentSyncCapability::Kind(_) => None,
13133    }
13134}
13135
13136/// Completion items are displayed in a `UniformList`.
13137/// Usually, those items are single-line strings, but in LSP responses,
13138/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13139/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13140/// 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,
13141/// breaking the completions menu presentation.
13142///
13143/// 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.
13144fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13145    let mut new_text = String::with_capacity(label.text.len());
13146    let mut offset_map = vec![0; label.text.len() + 1];
13147    let mut last_char_was_space = false;
13148    let mut new_idx = 0;
13149    let mut chars = label.text.char_indices().fuse();
13150    let mut newlines_removed = false;
13151
13152    while let Some((idx, c)) = chars.next() {
13153        offset_map[idx] = new_idx;
13154
13155        match c {
13156            '\n' if last_char_was_space => {
13157                newlines_removed = true;
13158            }
13159            '\t' | ' ' if last_char_was_space => {}
13160            '\n' if !last_char_was_space => {
13161                new_text.push(' ');
13162                new_idx += 1;
13163                last_char_was_space = true;
13164                newlines_removed = true;
13165            }
13166            ' ' | '\t' => {
13167                new_text.push(' ');
13168                new_idx += 1;
13169                last_char_was_space = true;
13170            }
13171            _ => {
13172                new_text.push(c);
13173                new_idx += c.len_utf8();
13174                last_char_was_space = false;
13175            }
13176        }
13177    }
13178    offset_map[label.text.len()] = new_idx;
13179
13180    // Only modify the label if newlines were removed.
13181    if !newlines_removed {
13182        return;
13183    }
13184
13185    let last_index = new_idx;
13186    let mut run_ranges_errors = Vec::new();
13187    label.runs.retain_mut(|(range, _)| {
13188        match offset_map.get(range.start) {
13189            Some(&start) => range.start = start,
13190            None => {
13191                run_ranges_errors.push(range.clone());
13192                return false;
13193            }
13194        }
13195
13196        match offset_map.get(range.end) {
13197            Some(&end) => range.end = end,
13198            None => {
13199                run_ranges_errors.push(range.clone());
13200                range.end = last_index;
13201            }
13202        }
13203        true
13204    });
13205    if !run_ranges_errors.is_empty() {
13206        log::error!(
13207            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13208            label.text
13209        );
13210    }
13211
13212    let mut wrong_filter_range = None;
13213    if label.filter_range == (0..label.text.len()) {
13214        label.filter_range = 0..new_text.len();
13215    } else {
13216        let mut original_filter_range = Some(label.filter_range.clone());
13217        match offset_map.get(label.filter_range.start) {
13218            Some(&start) => label.filter_range.start = start,
13219            None => {
13220                wrong_filter_range = original_filter_range.take();
13221                label.filter_range.start = last_index;
13222            }
13223        }
13224
13225        match offset_map.get(label.filter_range.end) {
13226            Some(&end) => label.filter_range.end = end,
13227            None => {
13228                wrong_filter_range = original_filter_range.take();
13229                label.filter_range.end = last_index;
13230            }
13231        }
13232    }
13233    if let Some(wrong_filter_range) = wrong_filter_range {
13234        log::error!(
13235            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13236            label.text
13237        );
13238    }
13239
13240    label.text = new_text;
13241}
13242
13243#[cfg(test)]
13244mod tests {
13245    use language::HighlightId;
13246
13247    use super::*;
13248
13249    #[test]
13250    fn test_glob_literal_prefix() {
13251        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13252        assert_eq!(
13253            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13254            Path::new("node_modules")
13255        );
13256        assert_eq!(
13257            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13258            Path::new("foo")
13259        );
13260        assert_eq!(
13261            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13262            Path::new("foo/bar/baz.js")
13263        );
13264
13265        #[cfg(target_os = "windows")]
13266        {
13267            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13268            assert_eq!(
13269                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13270                Path::new("node_modules")
13271            );
13272            assert_eq!(
13273                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13274                Path::new("foo")
13275            );
13276            assert_eq!(
13277                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13278                Path::new("foo/bar/baz.js")
13279            );
13280        }
13281    }
13282
13283    #[test]
13284    fn test_multi_len_chars_normalization() {
13285        let mut label = CodeLabel {
13286            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13287            runs: vec![(0..6, HighlightId(1))],
13288            filter_range: 0..6,
13289        };
13290        ensure_uniform_list_compatible_label(&mut label);
13291        assert_eq!(
13292            label,
13293            CodeLabel {
13294                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13295                runs: vec![(0..6, HighlightId(1))],
13296                filter_range: 0..6,
13297            }
13298        );
13299    }
13300}