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