lsp_store.rs

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