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