lsp_store.rs

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