lsp_store.rs

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