lsp_store.rs

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