lsp_store.rs

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