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