lsp_store.rs

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