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