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, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   83    WorkspaceFolder, notification::DidRenameFiles,
   84};
   85use node_runtime::read_package_installed_version;
   86use parking_lot::Mutex;
   87use postage::{mpsc, sink::Sink, stream::Stream, watch};
   88use rand::prelude::*;
   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};
  117
  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<Uri>>> = 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                            Uri::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::Uri::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::Uri,
 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::new(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::new(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 = Uri::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::Uri::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::Uri::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::Uri::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        abs_path: lsp::Uri,
 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            // Uri is immutable, so we can't modify the scheme
 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::Uri::from_file_path(old_path)
 9234                .ok()
 9235                .map(|uri| uri.to_string())?;
 9236            let new_uri = lsp::Uri::from_file_path(new_path)
 9237                .ok()
 9238                .map(|uri| uri.to_string())?;
 9239
 9240            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9241                let Some(filter) = local_store
 9242                    .language_server_paths_watched_for_rename
 9243                    .get(&language_server.server_id())
 9244                else {
 9245                    continue;
 9246                };
 9247
 9248                if filter.should_send_did_rename(&old_uri, is_dir) {
 9249                    language_server
 9250                        .notify::<DidRenameFiles>(&RenameFilesParams {
 9251                            files: vec![FileRename {
 9252                                old_uri: old_uri.clone(),
 9253                                new_uri: new_uri.clone(),
 9254                            }],
 9255                        })
 9256                        .ok();
 9257                }
 9258            }
 9259            Some(())
 9260        });
 9261    }
 9262
 9263    pub(super) fn will_rename_entry(
 9264        this: WeakEntity<Self>,
 9265        worktree_id: WorktreeId,
 9266        old_path: &Path,
 9267        new_path: &Path,
 9268        is_dir: bool,
 9269        cx: AsyncApp,
 9270    ) -> Task<ProjectTransaction> {
 9271        let old_uri = lsp::Uri::from_file_path(old_path)
 9272            .ok()
 9273            .map(|uri| uri.to_string());
 9274        let new_uri = lsp::Uri::from_file_path(new_path)
 9275            .ok()
 9276            .map(|uri| uri.to_string());
 9277        cx.spawn(async move |cx| {
 9278            let mut tasks = vec![];
 9279            this.update(cx, |this, cx| {
 9280                let local_store = this.as_local()?;
 9281                let old_uri = old_uri?;
 9282                let new_uri = new_uri?;
 9283                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9284                    let Some(filter) = local_store
 9285                        .language_server_paths_watched_for_rename
 9286                        .get(&language_server.server_id())
 9287                    else {
 9288                        continue;
 9289                    };
 9290
 9291                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9292                        let apply_edit = cx.spawn({
 9293                            let old_uri = old_uri.clone();
 9294                            let new_uri = new_uri.clone();
 9295                            let language_server = language_server.clone();
 9296                            async move |this, cx| {
 9297                                let edit = language_server
 9298                                    .request::<WillRenameFiles>(RenameFilesParams {
 9299                                        files: vec![FileRename { old_uri, new_uri }],
 9300                                    })
 9301                                    .await
 9302                                    .into_response()
 9303                                    .context("will rename files")
 9304                                    .log_err()
 9305                                    .flatten()?;
 9306
 9307                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9308                                    this.upgrade()?,
 9309                                    edit,
 9310                                    false,
 9311                                    language_server.clone(),
 9312                                    cx,
 9313                                )
 9314                                .await
 9315                                .ok()?;
 9316                                Some(transaction)
 9317                            }
 9318                        });
 9319                        tasks.push(apply_edit);
 9320                    }
 9321                }
 9322                Some(())
 9323            })
 9324            .ok()
 9325            .flatten();
 9326            let mut merged_transaction = ProjectTransaction::default();
 9327            for task in tasks {
 9328                // Await on tasks sequentially so that the order of application of edits is deterministic
 9329                // (at least with regards to the order of registration of language servers)
 9330                if let Some(transaction) = task.await {
 9331                    for (buffer, buffer_transaction) in transaction.0 {
 9332                        merged_transaction.0.insert(buffer, buffer_transaction);
 9333                    }
 9334                }
 9335            }
 9336            merged_transaction
 9337        })
 9338    }
 9339
 9340    fn lsp_notify_abs_paths_changed(
 9341        &mut self,
 9342        server_id: LanguageServerId,
 9343        changes: Vec<PathEvent>,
 9344    ) {
 9345        maybe!({
 9346            let server = self.language_server_for_id(server_id)?;
 9347            let changes = changes
 9348                .into_iter()
 9349                .filter_map(|event| {
 9350                    let typ = match event.kind? {
 9351                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9352                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9353                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9354                    };
 9355                    Some(lsp::FileEvent {
 9356                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9357                        typ,
 9358                    })
 9359                })
 9360                .collect::<Vec<_>>();
 9361            if !changes.is_empty() {
 9362                server
 9363                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9364                        &lsp::DidChangeWatchedFilesParams { changes },
 9365                    )
 9366                    .ok();
 9367            }
 9368            Some(())
 9369        });
 9370    }
 9371
 9372    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9373        self.as_local()?.language_server_for_id(id)
 9374    }
 9375
 9376    fn on_lsp_progress(
 9377        &mut self,
 9378        progress: lsp::ProgressParams,
 9379        language_server_id: LanguageServerId,
 9380        disk_based_diagnostics_progress_token: Option<String>,
 9381        cx: &mut Context<Self>,
 9382    ) {
 9383        let token = match progress.token {
 9384            lsp::NumberOrString::String(token) => token,
 9385            lsp::NumberOrString::Number(token) => {
 9386                log::info!("skipping numeric progress token {}", token);
 9387                return;
 9388            }
 9389        };
 9390
 9391        match progress.value {
 9392            lsp::ProgressParamsValue::WorkDone(progress) => {
 9393                self.handle_work_done_progress(
 9394                    progress,
 9395                    language_server_id,
 9396                    disk_based_diagnostics_progress_token,
 9397                    token,
 9398                    cx,
 9399                );
 9400            }
 9401            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9402                if let Some(LanguageServerState::Running {
 9403                    workspace_refresh_task: Some(workspace_refresh_task),
 9404                    ..
 9405                }) = self
 9406                    .as_local_mut()
 9407                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9408                {
 9409                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9410                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9411                }
 9412            }
 9413        }
 9414    }
 9415
 9416    fn handle_work_done_progress(
 9417        &mut self,
 9418        progress: lsp::WorkDoneProgress,
 9419        language_server_id: LanguageServerId,
 9420        disk_based_diagnostics_progress_token: Option<String>,
 9421        token: String,
 9422        cx: &mut Context<Self>,
 9423    ) {
 9424        let language_server_status =
 9425            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9426                status
 9427            } else {
 9428                return;
 9429            };
 9430
 9431        if !language_server_status.progress_tokens.contains(&token) {
 9432            return;
 9433        }
 9434
 9435        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9436            .as_ref()
 9437            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9438
 9439        match progress {
 9440            lsp::WorkDoneProgress::Begin(report) => {
 9441                if is_disk_based_diagnostics_progress {
 9442                    self.disk_based_diagnostics_started(language_server_id, cx);
 9443                }
 9444                self.on_lsp_work_start(
 9445                    language_server_id,
 9446                    token.clone(),
 9447                    LanguageServerProgress {
 9448                        title: Some(report.title),
 9449                        is_disk_based_diagnostics_progress,
 9450                        is_cancellable: report.cancellable.unwrap_or(false),
 9451                        message: report.message.clone(),
 9452                        percentage: report.percentage.map(|p| p as usize),
 9453                        last_update_at: cx.background_executor().now(),
 9454                    },
 9455                    cx,
 9456                );
 9457            }
 9458            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9459                language_server_id,
 9460                token,
 9461                LanguageServerProgress {
 9462                    title: None,
 9463                    is_disk_based_diagnostics_progress,
 9464                    is_cancellable: report.cancellable.unwrap_or(false),
 9465                    message: report.message,
 9466                    percentage: report.percentage.map(|p| p as usize),
 9467                    last_update_at: cx.background_executor().now(),
 9468                },
 9469                cx,
 9470            ),
 9471            lsp::WorkDoneProgress::End(_) => {
 9472                language_server_status.progress_tokens.remove(&token);
 9473                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9474                if is_disk_based_diagnostics_progress {
 9475                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9476                }
 9477            }
 9478        }
 9479    }
 9480
 9481    fn on_lsp_work_start(
 9482        &mut self,
 9483        language_server_id: LanguageServerId,
 9484        token: String,
 9485        progress: LanguageServerProgress,
 9486        cx: &mut Context<Self>,
 9487    ) {
 9488        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9489            status.pending_work.insert(token.clone(), progress.clone());
 9490            cx.notify();
 9491        }
 9492        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9493            language_server_id,
 9494            name: self
 9495                .language_server_adapter_for_id(language_server_id)
 9496                .map(|adapter| adapter.name()),
 9497            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9498                token,
 9499                title: progress.title,
 9500                message: progress.message,
 9501                percentage: progress.percentage.map(|p| p as u32),
 9502                is_cancellable: Some(progress.is_cancellable),
 9503            }),
 9504        })
 9505    }
 9506
 9507    fn on_lsp_work_progress(
 9508        &mut self,
 9509        language_server_id: LanguageServerId,
 9510        token: String,
 9511        progress: LanguageServerProgress,
 9512        cx: &mut Context<Self>,
 9513    ) {
 9514        let mut did_update = false;
 9515        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9516            match status.pending_work.entry(token.clone()) {
 9517                btree_map::Entry::Vacant(entry) => {
 9518                    entry.insert(progress.clone());
 9519                    did_update = true;
 9520                }
 9521                btree_map::Entry::Occupied(mut entry) => {
 9522                    let entry = entry.get_mut();
 9523                    if (progress.last_update_at - entry.last_update_at)
 9524                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9525                    {
 9526                        entry.last_update_at = progress.last_update_at;
 9527                        if progress.message.is_some() {
 9528                            entry.message = progress.message.clone();
 9529                        }
 9530                        if progress.percentage.is_some() {
 9531                            entry.percentage = progress.percentage;
 9532                        }
 9533                        if progress.is_cancellable != entry.is_cancellable {
 9534                            entry.is_cancellable = progress.is_cancellable;
 9535                        }
 9536                        did_update = true;
 9537                    }
 9538                }
 9539            }
 9540        }
 9541
 9542        if did_update {
 9543            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9544                language_server_id,
 9545                name: self
 9546                    .language_server_adapter_for_id(language_server_id)
 9547                    .map(|adapter| adapter.name()),
 9548                message: proto::update_language_server::Variant::WorkProgress(
 9549                    proto::LspWorkProgress {
 9550                        token,
 9551                        message: progress.message,
 9552                        percentage: progress.percentage.map(|p| p as u32),
 9553                        is_cancellable: Some(progress.is_cancellable),
 9554                    },
 9555                ),
 9556            })
 9557        }
 9558    }
 9559
 9560    fn on_lsp_work_end(
 9561        &mut self,
 9562        language_server_id: LanguageServerId,
 9563        token: String,
 9564        cx: &mut Context<Self>,
 9565    ) {
 9566        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9567            if let Some(work) = status.pending_work.remove(&token)
 9568                && !work.is_disk_based_diagnostics_progress
 9569            {
 9570                cx.emit(LspStoreEvent::RefreshInlayHints);
 9571            }
 9572            cx.notify();
 9573        }
 9574
 9575        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9576            language_server_id,
 9577            name: self
 9578                .language_server_adapter_for_id(language_server_id)
 9579                .map(|adapter| adapter.name()),
 9580            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9581        })
 9582    }
 9583
 9584    pub async fn handle_resolve_completion_documentation(
 9585        this: Entity<Self>,
 9586        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9587        mut cx: AsyncApp,
 9588    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9589        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9590
 9591        let completion = this
 9592            .read_with(&cx, |this, cx| {
 9593                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9594                let server = this
 9595                    .language_server_for_id(id)
 9596                    .with_context(|| format!("No language server {id}"))?;
 9597
 9598                anyhow::Ok(cx.background_spawn(async move {
 9599                    let can_resolve = server
 9600                        .capabilities()
 9601                        .completion_provider
 9602                        .as_ref()
 9603                        .and_then(|options| options.resolve_provider)
 9604                        .unwrap_or(false);
 9605                    if can_resolve {
 9606                        server
 9607                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9608                            .await
 9609                            .into_response()
 9610                            .context("resolve completion item")
 9611                    } else {
 9612                        anyhow::Ok(lsp_completion)
 9613                    }
 9614                }))
 9615            })??
 9616            .await?;
 9617
 9618        let mut documentation_is_markdown = false;
 9619        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9620        let documentation = match completion.documentation {
 9621            Some(lsp::Documentation::String(text)) => text,
 9622
 9623            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9624                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9625                value
 9626            }
 9627
 9628            _ => String::new(),
 9629        };
 9630
 9631        // If we have a new buffer_id, that means we're talking to a new client
 9632        // and want to check for new text_edits in the completion too.
 9633        let mut old_replace_start = None;
 9634        let mut old_replace_end = None;
 9635        let mut old_insert_start = None;
 9636        let mut old_insert_end = None;
 9637        let mut new_text = String::default();
 9638        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9639            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9640                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9641                anyhow::Ok(buffer.read(cx).snapshot())
 9642            })??;
 9643
 9644            if let Some(text_edit) = completion.text_edit.as_ref() {
 9645                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9646
 9647                if let Some(mut edit) = edit {
 9648                    LineEnding::normalize(&mut edit.new_text);
 9649
 9650                    new_text = edit.new_text;
 9651                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9652                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9653                    if let Some(insert_range) = edit.insert_range {
 9654                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9655                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9656                    }
 9657                }
 9658            }
 9659        }
 9660
 9661        Ok(proto::ResolveCompletionDocumentationResponse {
 9662            documentation,
 9663            documentation_is_markdown,
 9664            old_replace_start,
 9665            old_replace_end,
 9666            new_text,
 9667            lsp_completion,
 9668            old_insert_start,
 9669            old_insert_end,
 9670        })
 9671    }
 9672
 9673    async fn handle_on_type_formatting(
 9674        this: Entity<Self>,
 9675        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9676        mut cx: AsyncApp,
 9677    ) -> Result<proto::OnTypeFormattingResponse> {
 9678        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9679            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9680            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9681            let position = envelope
 9682                .payload
 9683                .position
 9684                .and_then(deserialize_anchor)
 9685                .context("invalid position")?;
 9686            anyhow::Ok(this.apply_on_type_formatting(
 9687                buffer,
 9688                position,
 9689                envelope.payload.trigger.clone(),
 9690                cx,
 9691            ))
 9692        })??;
 9693
 9694        let transaction = on_type_formatting
 9695            .await?
 9696            .as_ref()
 9697            .map(language::proto::serialize_transaction);
 9698        Ok(proto::OnTypeFormattingResponse { transaction })
 9699    }
 9700
 9701    async fn handle_refresh_inlay_hints(
 9702        this: Entity<Self>,
 9703        _: TypedEnvelope<proto::RefreshInlayHints>,
 9704        mut cx: AsyncApp,
 9705    ) -> Result<proto::Ack> {
 9706        this.update(&mut cx, |_, cx| {
 9707            cx.emit(LspStoreEvent::RefreshInlayHints);
 9708        })?;
 9709        Ok(proto::Ack {})
 9710    }
 9711
 9712    async fn handle_pull_workspace_diagnostics(
 9713        lsp_store: Entity<Self>,
 9714        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9715        mut cx: AsyncApp,
 9716    ) -> Result<proto::Ack> {
 9717        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9718        lsp_store.update(&mut cx, |lsp_store, _| {
 9719            lsp_store.pull_workspace_diagnostics(server_id);
 9720        })?;
 9721        Ok(proto::Ack {})
 9722    }
 9723
 9724    async fn handle_inlay_hints(
 9725        this: Entity<Self>,
 9726        envelope: TypedEnvelope<proto::InlayHints>,
 9727        mut cx: AsyncApp,
 9728    ) -> Result<proto::InlayHintsResponse> {
 9729        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9730        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9731        let buffer = this.update(&mut cx, |this, cx| {
 9732            this.buffer_store.read(cx).get_existing(buffer_id)
 9733        })??;
 9734        buffer
 9735            .update(&mut cx, |buffer, _| {
 9736                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9737            })?
 9738            .await
 9739            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9740
 9741        let start = envelope
 9742            .payload
 9743            .start
 9744            .and_then(deserialize_anchor)
 9745            .context("missing range start")?;
 9746        let end = envelope
 9747            .payload
 9748            .end
 9749            .and_then(deserialize_anchor)
 9750            .context("missing range end")?;
 9751        let buffer_hints = this
 9752            .update(&mut cx, |lsp_store, cx| {
 9753                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9754            })?
 9755            .await
 9756            .context("inlay hints fetch")?;
 9757
 9758        this.update(&mut cx, |project, cx| {
 9759            InlayHints::response_to_proto(
 9760                buffer_hints,
 9761                project,
 9762                sender_id,
 9763                &buffer.read(cx).version(),
 9764                cx,
 9765            )
 9766        })
 9767    }
 9768
 9769    async fn handle_get_color_presentation(
 9770        lsp_store: Entity<Self>,
 9771        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9772        mut cx: AsyncApp,
 9773    ) -> Result<proto::GetColorPresentationResponse> {
 9774        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9775        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9776            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9777        })??;
 9778
 9779        let color = envelope
 9780            .payload
 9781            .color
 9782            .context("invalid color resolve request")?;
 9783        let start = color
 9784            .lsp_range_start
 9785            .context("invalid color resolve request")?;
 9786        let end = color
 9787            .lsp_range_end
 9788            .context("invalid color resolve request")?;
 9789
 9790        let color = DocumentColor {
 9791            lsp_range: lsp::Range {
 9792                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9793                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9794            },
 9795            color: lsp::Color {
 9796                red: color.red,
 9797                green: color.green,
 9798                blue: color.blue,
 9799                alpha: color.alpha,
 9800            },
 9801            resolved: false,
 9802            color_presentations: Vec::new(),
 9803        };
 9804        let resolved_color = lsp_store
 9805            .update(&mut cx, |lsp_store, cx| {
 9806                lsp_store.resolve_color_presentation(
 9807                    color,
 9808                    buffer.clone(),
 9809                    LanguageServerId(envelope.payload.server_id as usize),
 9810                    cx,
 9811                )
 9812            })?
 9813            .await
 9814            .context("resolving color presentation")?;
 9815
 9816        Ok(proto::GetColorPresentationResponse {
 9817            presentations: resolved_color
 9818                .color_presentations
 9819                .into_iter()
 9820                .map(|presentation| proto::ColorPresentation {
 9821                    label: presentation.label.to_string(),
 9822                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9823                    additional_text_edits: presentation
 9824                        .additional_text_edits
 9825                        .into_iter()
 9826                        .map(serialize_lsp_edit)
 9827                        .collect(),
 9828                })
 9829                .collect(),
 9830        })
 9831    }
 9832
 9833    async fn handle_resolve_inlay_hint(
 9834        this: Entity<Self>,
 9835        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9836        mut cx: AsyncApp,
 9837    ) -> Result<proto::ResolveInlayHintResponse> {
 9838        let proto_hint = envelope
 9839            .payload
 9840            .hint
 9841            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9842        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9843            .context("resolved proto inlay hint conversion")?;
 9844        let buffer = this.update(&mut cx, |this, cx| {
 9845            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9846            this.buffer_store.read(cx).get_existing(buffer_id)
 9847        })??;
 9848        let response_hint = this
 9849            .update(&mut cx, |this, cx| {
 9850                this.resolve_inlay_hint(
 9851                    hint,
 9852                    buffer,
 9853                    LanguageServerId(envelope.payload.language_server_id as usize),
 9854                    cx,
 9855                )
 9856            })?
 9857            .await
 9858            .context("inlay hints fetch")?;
 9859        Ok(proto::ResolveInlayHintResponse {
 9860            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9861        })
 9862    }
 9863
 9864    async fn handle_refresh_code_lens(
 9865        this: Entity<Self>,
 9866        _: TypedEnvelope<proto::RefreshCodeLens>,
 9867        mut cx: AsyncApp,
 9868    ) -> Result<proto::Ack> {
 9869        this.update(&mut cx, |_, cx| {
 9870            cx.emit(LspStoreEvent::RefreshCodeLens);
 9871        })?;
 9872        Ok(proto::Ack {})
 9873    }
 9874
 9875    async fn handle_open_buffer_for_symbol(
 9876        this: Entity<Self>,
 9877        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9878        mut cx: AsyncApp,
 9879    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9880        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9881        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9882        let symbol = Self::deserialize_symbol(symbol)?;
 9883        let symbol = this.read_with(&cx, |this, _| {
 9884            let signature = this.symbol_signature(&symbol.path);
 9885            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9886            Ok(symbol)
 9887        })??;
 9888        let buffer = this
 9889            .update(&mut cx, |this, cx| {
 9890                this.open_buffer_for_symbol(
 9891                    &Symbol {
 9892                        language_server_name: symbol.language_server_name,
 9893                        source_worktree_id: symbol.source_worktree_id,
 9894                        source_language_server_id: symbol.source_language_server_id,
 9895                        path: symbol.path,
 9896                        name: symbol.name,
 9897                        kind: symbol.kind,
 9898                        range: symbol.range,
 9899                        signature: symbol.signature,
 9900                        label: CodeLabel {
 9901                            text: Default::default(),
 9902                            runs: Default::default(),
 9903                            filter_range: Default::default(),
 9904                        },
 9905                    },
 9906                    cx,
 9907                )
 9908            })?
 9909            .await?;
 9910
 9911        this.update(&mut cx, |this, cx| {
 9912            let is_private = buffer
 9913                .read(cx)
 9914                .file()
 9915                .map(|f| f.is_private())
 9916                .unwrap_or_default();
 9917            if is_private {
 9918                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9919            } else {
 9920                this.buffer_store
 9921                    .update(cx, |buffer_store, cx| {
 9922                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9923                    })
 9924                    .detach_and_log_err(cx);
 9925                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9926                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9927            }
 9928        })?
 9929    }
 9930
 9931    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9932        let mut hasher = Sha256::new();
 9933        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9934        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9935        hasher.update(self.nonce.to_be_bytes());
 9936        hasher.finalize().as_slice().try_into().unwrap()
 9937    }
 9938
 9939    pub async fn handle_get_project_symbols(
 9940        this: Entity<Self>,
 9941        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9942        mut cx: AsyncApp,
 9943    ) -> Result<proto::GetProjectSymbolsResponse> {
 9944        let symbols = this
 9945            .update(&mut cx, |this, cx| {
 9946                this.symbols(&envelope.payload.query, cx)
 9947            })?
 9948            .await?;
 9949
 9950        Ok(proto::GetProjectSymbolsResponse {
 9951            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9952        })
 9953    }
 9954
 9955    pub async fn handle_restart_language_servers(
 9956        this: Entity<Self>,
 9957        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9958        mut cx: AsyncApp,
 9959    ) -> Result<proto::Ack> {
 9960        this.update(&mut cx, |lsp_store, cx| {
 9961            let buffers =
 9962                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9963            lsp_store.restart_language_servers_for_buffers(
 9964                buffers,
 9965                envelope
 9966                    .payload
 9967                    .only_servers
 9968                    .into_iter()
 9969                    .filter_map(|selector| {
 9970                        Some(match selector.selector? {
 9971                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9972                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9973                            }
 9974                            proto::language_server_selector::Selector::Name(name) => {
 9975                                LanguageServerSelector::Name(LanguageServerName(
 9976                                    SharedString::from(name),
 9977                                ))
 9978                            }
 9979                        })
 9980                    })
 9981                    .collect(),
 9982                cx,
 9983            );
 9984        })?;
 9985
 9986        Ok(proto::Ack {})
 9987    }
 9988
 9989    pub async fn handle_stop_language_servers(
 9990        lsp_store: Entity<Self>,
 9991        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9992        mut cx: AsyncApp,
 9993    ) -> Result<proto::Ack> {
 9994        lsp_store.update(&mut cx, |lsp_store, cx| {
 9995            if envelope.payload.all
 9996                && envelope.payload.also_servers.is_empty()
 9997                && envelope.payload.buffer_ids.is_empty()
 9998            {
 9999                lsp_store.stop_all_language_servers(cx);
10000            } else {
10001                let buffers =
10002                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10003                lsp_store
10004                    .stop_language_servers_for_buffers(
10005                        buffers,
10006                        envelope
10007                            .payload
10008                            .also_servers
10009                            .into_iter()
10010                            .filter_map(|selector| {
10011                                Some(match selector.selector? {
10012                                    proto::language_server_selector::Selector::ServerId(
10013                                        server_id,
10014                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10015                                        server_id,
10016                                    )),
10017                                    proto::language_server_selector::Selector::Name(name) => {
10018                                        LanguageServerSelector::Name(LanguageServerName(
10019                                            SharedString::from(name),
10020                                        ))
10021                                    }
10022                                })
10023                            })
10024                            .collect(),
10025                        cx,
10026                    )
10027                    .detach_and_log_err(cx);
10028            }
10029        })?;
10030
10031        Ok(proto::Ack {})
10032    }
10033
10034    pub async fn handle_cancel_language_server_work(
10035        this: Entity<Self>,
10036        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10037        mut cx: AsyncApp,
10038    ) -> Result<proto::Ack> {
10039        this.update(&mut cx, |this, cx| {
10040            if let Some(work) = envelope.payload.work {
10041                match work {
10042                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10043                        let buffers =
10044                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10045                        this.cancel_language_server_work_for_buffers(buffers, cx);
10046                    }
10047                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10048                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10049                        this.cancel_language_server_work(server_id, work.token, cx);
10050                    }
10051                }
10052            }
10053        })?;
10054
10055        Ok(proto::Ack {})
10056    }
10057
10058    fn buffer_ids_to_buffers(
10059        &mut self,
10060        buffer_ids: impl Iterator<Item = u64>,
10061        cx: &mut Context<Self>,
10062    ) -> Vec<Entity<Buffer>> {
10063        buffer_ids
10064            .into_iter()
10065            .flat_map(|buffer_id| {
10066                self.buffer_store
10067                    .read(cx)
10068                    .get(BufferId::new(buffer_id).log_err()?)
10069            })
10070            .collect::<Vec<_>>()
10071    }
10072
10073    async fn handle_apply_additional_edits_for_completion(
10074        this: Entity<Self>,
10075        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10076        mut cx: AsyncApp,
10077    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10078        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10079            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10080            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10081            let completion = Self::deserialize_completion(
10082                envelope.payload.completion.context("invalid completion")?,
10083            )?;
10084            anyhow::Ok((buffer, completion))
10085        })??;
10086
10087        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10088            this.apply_additional_edits_for_completion(
10089                buffer,
10090                Rc::new(RefCell::new(Box::new([Completion {
10091                    replace_range: completion.replace_range,
10092                    new_text: completion.new_text,
10093                    source: completion.source,
10094                    documentation: None,
10095                    label: CodeLabel {
10096                        text: Default::default(),
10097                        runs: Default::default(),
10098                        filter_range: Default::default(),
10099                    },
10100                    insert_text_mode: None,
10101                    icon_path: None,
10102                    confirm: None,
10103                }]))),
10104                0,
10105                false,
10106                cx,
10107            )
10108        })?;
10109
10110        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10111            transaction: apply_additional_edits
10112                .await?
10113                .as_ref()
10114                .map(language::proto::serialize_transaction),
10115        })
10116    }
10117
10118    pub fn last_formatting_failure(&self) -> Option<&str> {
10119        self.last_formatting_failure.as_deref()
10120    }
10121
10122    pub fn reset_last_formatting_failure(&mut self) {
10123        self.last_formatting_failure = None;
10124    }
10125
10126    pub fn environment_for_buffer(
10127        &self,
10128        buffer: &Entity<Buffer>,
10129        cx: &mut Context<Self>,
10130    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10131        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10132            environment.update(cx, |env, cx| {
10133                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10134            })
10135        } else {
10136            Task::ready(None).shared()
10137        }
10138    }
10139
10140    pub fn format(
10141        &mut self,
10142        buffers: HashSet<Entity<Buffer>>,
10143        target: LspFormatTarget,
10144        push_to_history: bool,
10145        trigger: FormatTrigger,
10146        cx: &mut Context<Self>,
10147    ) -> Task<anyhow::Result<ProjectTransaction>> {
10148        let logger = zlog::scoped!("format");
10149        if self.as_local().is_some() {
10150            zlog::trace!(logger => "Formatting locally");
10151            let logger = zlog::scoped!(logger => "local");
10152            let buffers = buffers
10153                .into_iter()
10154                .map(|buffer_handle| {
10155                    let buffer = buffer_handle.read(cx);
10156                    let buffer_abs_path = File::from_dyn(buffer.file())
10157                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10158
10159                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10160                })
10161                .collect::<Vec<_>>();
10162
10163            cx.spawn(async move |lsp_store, cx| {
10164                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10165
10166                for (handle, abs_path, id) in buffers {
10167                    let env = lsp_store
10168                        .update(cx, |lsp_store, cx| {
10169                            lsp_store.environment_for_buffer(&handle, cx)
10170                        })?
10171                        .await;
10172
10173                    let ranges = match &target {
10174                        LspFormatTarget::Buffers => None,
10175                        LspFormatTarget::Ranges(ranges) => {
10176                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10177                        }
10178                    };
10179
10180                    formattable_buffers.push(FormattableBuffer {
10181                        handle,
10182                        abs_path,
10183                        env,
10184                        ranges,
10185                    });
10186                }
10187                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10188
10189                let format_timer = zlog::time!(logger => "Formatting buffers");
10190                let result = LocalLspStore::format_locally(
10191                    lsp_store.clone(),
10192                    formattable_buffers,
10193                    push_to_history,
10194                    trigger,
10195                    logger,
10196                    cx,
10197                )
10198                .await;
10199                format_timer.end();
10200
10201                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10202
10203                lsp_store.update(cx, |lsp_store, _| {
10204                    lsp_store.update_last_formatting_failure(&result);
10205                })?;
10206
10207                result
10208            })
10209        } else if let Some((client, project_id)) = self.upstream_client() {
10210            zlog::trace!(logger => "Formatting remotely");
10211            let logger = zlog::scoped!(logger => "remote");
10212            // Don't support formatting ranges via remote
10213            match target {
10214                LspFormatTarget::Buffers => {}
10215                LspFormatTarget::Ranges(_) => {
10216                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10217                    return Task::ready(Ok(ProjectTransaction::default()));
10218                }
10219            }
10220
10221            let buffer_store = self.buffer_store();
10222            cx.spawn(async move |lsp_store, cx| {
10223                zlog::trace!(logger => "Sending remote format request");
10224                let request_timer = zlog::time!(logger => "remote format request");
10225                let result = client
10226                    .request(proto::FormatBuffers {
10227                        project_id,
10228                        trigger: trigger as i32,
10229                        buffer_ids: buffers
10230                            .iter()
10231                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10232                            .collect::<Result<_>>()?,
10233                    })
10234                    .await
10235                    .and_then(|result| result.transaction.context("missing transaction"));
10236                request_timer.end();
10237
10238                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10239
10240                lsp_store.update(cx, |lsp_store, _| {
10241                    lsp_store.update_last_formatting_failure(&result);
10242                })?;
10243
10244                let transaction_response = result?;
10245                let _timer = zlog::time!(logger => "deserializing project transaction");
10246                buffer_store
10247                    .update(cx, |buffer_store, cx| {
10248                        buffer_store.deserialize_project_transaction(
10249                            transaction_response,
10250                            push_to_history,
10251                            cx,
10252                        )
10253                    })?
10254                    .await
10255            })
10256        } else {
10257            zlog::trace!(logger => "Not formatting");
10258            Task::ready(Ok(ProjectTransaction::default()))
10259        }
10260    }
10261
10262    async fn handle_format_buffers(
10263        this: Entity<Self>,
10264        envelope: TypedEnvelope<proto::FormatBuffers>,
10265        mut cx: AsyncApp,
10266    ) -> Result<proto::FormatBuffersResponse> {
10267        let sender_id = envelope.original_sender_id().unwrap_or_default();
10268        let format = this.update(&mut cx, |this, cx| {
10269            let mut buffers = HashSet::default();
10270            for buffer_id in &envelope.payload.buffer_ids {
10271                let buffer_id = BufferId::new(*buffer_id)?;
10272                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10273            }
10274            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10275            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10276        })??;
10277
10278        let project_transaction = format.await?;
10279        let project_transaction = this.update(&mut cx, |this, cx| {
10280            this.buffer_store.update(cx, |buffer_store, cx| {
10281                buffer_store.serialize_project_transaction_for_peer(
10282                    project_transaction,
10283                    sender_id,
10284                    cx,
10285                )
10286            })
10287        })?;
10288        Ok(proto::FormatBuffersResponse {
10289            transaction: Some(project_transaction),
10290        })
10291    }
10292
10293    async fn handle_apply_code_action_kind(
10294        this: Entity<Self>,
10295        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10296        mut cx: AsyncApp,
10297    ) -> Result<proto::ApplyCodeActionKindResponse> {
10298        let sender_id = envelope.original_sender_id().unwrap_or_default();
10299        let format = this.update(&mut cx, |this, cx| {
10300            let mut buffers = HashSet::default();
10301            for buffer_id in &envelope.payload.buffer_ids {
10302                let buffer_id = BufferId::new(*buffer_id)?;
10303                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10304            }
10305            let kind = match envelope.payload.kind.as_str() {
10306                "" => CodeActionKind::EMPTY,
10307                "quickfix" => CodeActionKind::QUICKFIX,
10308                "refactor" => CodeActionKind::REFACTOR,
10309                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10310                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10311                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10312                "source" => CodeActionKind::SOURCE,
10313                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10314                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10315                _ => anyhow::bail!(
10316                    "Invalid code action kind {}",
10317                    envelope.payload.kind.as_str()
10318                ),
10319            };
10320            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10321        })??;
10322
10323        let project_transaction = format.await?;
10324        let project_transaction = this.update(&mut cx, |this, cx| {
10325            this.buffer_store.update(cx, |buffer_store, cx| {
10326                buffer_store.serialize_project_transaction_for_peer(
10327                    project_transaction,
10328                    sender_id,
10329                    cx,
10330                )
10331            })
10332        })?;
10333        Ok(proto::ApplyCodeActionKindResponse {
10334            transaction: Some(project_transaction),
10335        })
10336    }
10337
10338    async fn shutdown_language_server(
10339        server_state: Option<LanguageServerState>,
10340        name: LanguageServerName,
10341        cx: &mut AsyncApp,
10342    ) {
10343        let server = match server_state {
10344            Some(LanguageServerState::Starting { startup, .. }) => {
10345                let mut timer = cx
10346                    .background_executor()
10347                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10348                    .fuse();
10349
10350                select! {
10351                    server = startup.fuse() => server,
10352                    () = timer => {
10353                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10354                        None
10355                    },
10356                }
10357            }
10358
10359            Some(LanguageServerState::Running { server, .. }) => Some(server),
10360
10361            None => None,
10362        };
10363
10364        if let Some(server) = server
10365            && let Some(shutdown) = server.shutdown()
10366        {
10367            shutdown.await;
10368        }
10369    }
10370
10371    // Returns a list of all of the worktrees which no longer have a language server and the root path
10372    // for the stopped server
10373    fn stop_local_language_server(
10374        &mut self,
10375        server_id: LanguageServerId,
10376        cx: &mut Context<Self>,
10377    ) -> Task<()> {
10378        let local = match &mut self.mode {
10379            LspStoreMode::Local(local) => local,
10380            _ => {
10381                return Task::ready(());
10382            }
10383        };
10384
10385        // Remove this server ID from all entries in the given worktree.
10386        local
10387            .language_server_ids
10388            .retain(|_, state| state.id != server_id);
10389        self.buffer_store.update(cx, |buffer_store, cx| {
10390            for buffer in buffer_store.buffers() {
10391                buffer.update(cx, |buffer, cx| {
10392                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10393                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10394                });
10395            }
10396        });
10397
10398        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10399            summaries.retain(|path, summaries_by_server_id| {
10400                if summaries_by_server_id.remove(&server_id).is_some() {
10401                    if let Some((client, project_id)) = self.downstream_client.clone() {
10402                        client
10403                            .send(proto::UpdateDiagnosticSummary {
10404                                project_id,
10405                                worktree_id: worktree_id.to_proto(),
10406                                summary: Some(proto::DiagnosticSummary {
10407                                    path: path.as_ref().to_proto(),
10408                                    language_server_id: server_id.0 as u64,
10409                                    error_count: 0,
10410                                    warning_count: 0,
10411                                }),
10412                                more_summaries: Vec::new(),
10413                            })
10414                            .log_err();
10415                    }
10416                    !summaries_by_server_id.is_empty()
10417                } else {
10418                    true
10419                }
10420            });
10421        }
10422
10423        let local = self.as_local_mut().unwrap();
10424        for diagnostics in local.diagnostics.values_mut() {
10425            diagnostics.retain(|_, diagnostics_by_server_id| {
10426                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10427                    diagnostics_by_server_id.remove(ix);
10428                    !diagnostics_by_server_id.is_empty()
10429                } else {
10430                    true
10431                }
10432            });
10433        }
10434        local.language_server_watched_paths.remove(&server_id);
10435
10436        let server_state = local.language_servers.remove(&server_id);
10437        self.cleanup_lsp_data(server_id);
10438        let name = self
10439            .language_server_statuses
10440            .remove(&server_id)
10441            .map(|status| status.name)
10442            .or_else(|| {
10443                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10444                    Some(adapter.name())
10445                } else {
10446                    None
10447                }
10448            });
10449
10450        if let Some(name) = name {
10451            log::info!("stopping language server {name}");
10452            self.languages
10453                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10454            cx.notify();
10455
10456            return cx.spawn(async move |lsp_store, cx| {
10457                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10458                lsp_store
10459                    .update(cx, |lsp_store, cx| {
10460                        lsp_store
10461                            .languages
10462                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10463                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10464                        cx.notify();
10465                    })
10466                    .ok();
10467            });
10468        }
10469
10470        if server_state.is_some() {
10471            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10472        }
10473        Task::ready(())
10474    }
10475
10476    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10477        if let Some((client, project_id)) = self.upstream_client() {
10478            let request = client.request(proto::StopLanguageServers {
10479                project_id,
10480                buffer_ids: Vec::new(),
10481                also_servers: Vec::new(),
10482                all: true,
10483            });
10484            cx.background_spawn(request).detach_and_log_err(cx);
10485        } else {
10486            let Some(local) = self.as_local_mut() else {
10487                return;
10488            };
10489            let language_servers_to_stop = local
10490                .language_server_ids
10491                .values()
10492                .map(|state| state.id)
10493                .collect();
10494            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10495            let tasks = language_servers_to_stop
10496                .into_iter()
10497                .map(|server| self.stop_local_language_server(server, cx))
10498                .collect::<Vec<_>>();
10499            cx.background_spawn(async move {
10500                futures::future::join_all(tasks).await;
10501            })
10502            .detach();
10503        }
10504    }
10505
10506    pub fn restart_language_servers_for_buffers(
10507        &mut self,
10508        buffers: Vec<Entity<Buffer>>,
10509        only_restart_servers: HashSet<LanguageServerSelector>,
10510        cx: &mut Context<Self>,
10511    ) {
10512        if let Some((client, project_id)) = self.upstream_client() {
10513            let request = client.request(proto::RestartLanguageServers {
10514                project_id,
10515                buffer_ids: buffers
10516                    .into_iter()
10517                    .map(|b| b.read(cx).remote_id().to_proto())
10518                    .collect(),
10519                only_servers: only_restart_servers
10520                    .into_iter()
10521                    .map(|selector| {
10522                        let selector = match selector {
10523                            LanguageServerSelector::Id(language_server_id) => {
10524                                proto::language_server_selector::Selector::ServerId(
10525                                    language_server_id.to_proto(),
10526                                )
10527                            }
10528                            LanguageServerSelector::Name(language_server_name) => {
10529                                proto::language_server_selector::Selector::Name(
10530                                    language_server_name.to_string(),
10531                                )
10532                            }
10533                        };
10534                        proto::LanguageServerSelector {
10535                            selector: Some(selector),
10536                        }
10537                    })
10538                    .collect(),
10539                all: false,
10540            });
10541            cx.background_spawn(request).detach_and_log_err(cx);
10542        } else {
10543            let stop_task = if only_restart_servers.is_empty() {
10544                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10545            } else {
10546                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10547            };
10548            cx.spawn(async move |lsp_store, cx| {
10549                stop_task.await;
10550                lsp_store
10551                    .update(cx, |lsp_store, cx| {
10552                        for buffer in buffers {
10553                            lsp_store.register_buffer_with_language_servers(
10554                                &buffer,
10555                                only_restart_servers.clone(),
10556                                true,
10557                                cx,
10558                            );
10559                        }
10560                    })
10561                    .ok()
10562            })
10563            .detach();
10564        }
10565    }
10566
10567    pub fn stop_language_servers_for_buffers(
10568        &mut self,
10569        buffers: Vec<Entity<Buffer>>,
10570        also_stop_servers: HashSet<LanguageServerSelector>,
10571        cx: &mut Context<Self>,
10572    ) -> Task<Result<()>> {
10573        if let Some((client, project_id)) = self.upstream_client() {
10574            let request = client.request(proto::StopLanguageServers {
10575                project_id,
10576                buffer_ids: buffers
10577                    .into_iter()
10578                    .map(|b| b.read(cx).remote_id().to_proto())
10579                    .collect(),
10580                also_servers: also_stop_servers
10581                    .into_iter()
10582                    .map(|selector| {
10583                        let selector = match selector {
10584                            LanguageServerSelector::Id(language_server_id) => {
10585                                proto::language_server_selector::Selector::ServerId(
10586                                    language_server_id.to_proto(),
10587                                )
10588                            }
10589                            LanguageServerSelector::Name(language_server_name) => {
10590                                proto::language_server_selector::Selector::Name(
10591                                    language_server_name.to_string(),
10592                                )
10593                            }
10594                        };
10595                        proto::LanguageServerSelector {
10596                            selector: Some(selector),
10597                        }
10598                    })
10599                    .collect(),
10600                all: false,
10601            });
10602            cx.background_spawn(async move {
10603                let _ = request.await?;
10604                Ok(())
10605            })
10606        } else {
10607            let task =
10608                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10609            cx.background_spawn(async move {
10610                task.await;
10611                Ok(())
10612            })
10613        }
10614    }
10615
10616    fn stop_local_language_servers_for_buffers(
10617        &mut self,
10618        buffers: &[Entity<Buffer>],
10619        also_stop_servers: HashSet<LanguageServerSelector>,
10620        cx: &mut Context<Self>,
10621    ) -> Task<()> {
10622        let Some(local) = self.as_local_mut() else {
10623            return Task::ready(());
10624        };
10625        let mut language_server_names_to_stop = BTreeSet::default();
10626        let mut language_servers_to_stop = also_stop_servers
10627            .into_iter()
10628            .flat_map(|selector| match selector {
10629                LanguageServerSelector::Id(id) => Some(id),
10630                LanguageServerSelector::Name(name) => {
10631                    language_server_names_to_stop.insert(name);
10632                    None
10633                }
10634            })
10635            .collect::<BTreeSet<_>>();
10636
10637        let mut covered_worktrees = HashSet::default();
10638        for buffer in buffers {
10639            buffer.update(cx, |buffer, cx| {
10640                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10641                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10642                    && covered_worktrees.insert(worktree_id)
10643                {
10644                    language_server_names_to_stop.retain(|name| {
10645                        let old_ids_count = language_servers_to_stop.len();
10646                        let all_language_servers_with_this_name = local
10647                            .language_server_ids
10648                            .iter()
10649                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10650                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10651                        old_ids_count == language_servers_to_stop.len()
10652                    });
10653                }
10654            });
10655        }
10656        for name in language_server_names_to_stop {
10657            language_servers_to_stop.extend(
10658                local
10659                    .language_server_ids
10660                    .iter()
10661                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10662            );
10663        }
10664
10665        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10666        let tasks = language_servers_to_stop
10667            .into_iter()
10668            .map(|server| self.stop_local_language_server(server, cx))
10669            .collect::<Vec<_>>();
10670
10671        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10672    }
10673
10674    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10675        let (worktree, relative_path) =
10676            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10677
10678        let project_path = ProjectPath {
10679            worktree_id: worktree.read(cx).id(),
10680            path: relative_path.into(),
10681        };
10682
10683        Some(
10684            self.buffer_store()
10685                .read(cx)
10686                .get_by_path(&project_path)?
10687                .read(cx),
10688        )
10689    }
10690
10691    #[cfg(any(test, feature = "test-support"))]
10692    pub fn update_diagnostics(
10693        &mut self,
10694        server_id: LanguageServerId,
10695        diagnostics: lsp::PublishDiagnosticsParams,
10696        result_id: Option<String>,
10697        source_kind: DiagnosticSourceKind,
10698        disk_based_sources: &[String],
10699        cx: &mut Context<Self>,
10700    ) -> Result<()> {
10701        self.merge_lsp_diagnostics(
10702            source_kind,
10703            vec![DocumentDiagnosticsUpdate {
10704                diagnostics,
10705                result_id,
10706                server_id,
10707                disk_based_sources: Cow::Borrowed(disk_based_sources),
10708            }],
10709            |_, _, _| false,
10710            cx,
10711        )
10712    }
10713
10714    pub fn merge_lsp_diagnostics(
10715        &mut self,
10716        source_kind: DiagnosticSourceKind,
10717        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10718        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10719        cx: &mut Context<Self>,
10720    ) -> Result<()> {
10721        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10722        let updates = lsp_diagnostics
10723            .into_iter()
10724            .filter_map(|update| {
10725                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10726                Some(DocumentDiagnosticsUpdate {
10727                    diagnostics: self.lsp_to_document_diagnostics(
10728                        abs_path,
10729                        source_kind,
10730                        update.server_id,
10731                        update.diagnostics,
10732                        &update.disk_based_sources,
10733                    ),
10734                    result_id: update.result_id,
10735                    server_id: update.server_id,
10736                    disk_based_sources: update.disk_based_sources,
10737                })
10738            })
10739            .collect();
10740        self.merge_diagnostic_entries(updates, merge, cx)?;
10741        Ok(())
10742    }
10743
10744    fn lsp_to_document_diagnostics(
10745        &mut self,
10746        document_abs_path: PathBuf,
10747        source_kind: DiagnosticSourceKind,
10748        server_id: LanguageServerId,
10749        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10750        disk_based_sources: &[String],
10751    ) -> DocumentDiagnostics {
10752        let mut diagnostics = Vec::default();
10753        let mut primary_diagnostic_group_ids = HashMap::default();
10754        let mut sources_by_group_id = HashMap::default();
10755        let mut supporting_diagnostics = HashMap::default();
10756
10757        let adapter = self.language_server_adapter_for_id(server_id);
10758
10759        // Ensure that primary diagnostics are always the most severe
10760        lsp_diagnostics
10761            .diagnostics
10762            .sort_by_key(|item| item.severity);
10763
10764        for diagnostic in &lsp_diagnostics.diagnostics {
10765            let source = diagnostic.source.as_ref();
10766            let range = range_from_lsp(diagnostic.range);
10767            let is_supporting = diagnostic
10768                .related_information
10769                .as_ref()
10770                .is_some_and(|infos| {
10771                    infos.iter().any(|info| {
10772                        primary_diagnostic_group_ids.contains_key(&(
10773                            source,
10774                            diagnostic.code.clone(),
10775                            range_from_lsp(info.location.range),
10776                        ))
10777                    })
10778                });
10779
10780            let is_unnecessary = diagnostic
10781                .tags
10782                .as_ref()
10783                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10784
10785            let underline = self
10786                .language_server_adapter_for_id(server_id)
10787                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10788
10789            if is_supporting {
10790                supporting_diagnostics.insert(
10791                    (source, diagnostic.code.clone(), range),
10792                    (diagnostic.severity, is_unnecessary),
10793                );
10794            } else {
10795                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10796                let is_disk_based =
10797                    source.is_some_and(|source| disk_based_sources.contains(source));
10798
10799                sources_by_group_id.insert(group_id, source);
10800                primary_diagnostic_group_ids
10801                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10802
10803                diagnostics.push(DiagnosticEntry {
10804                    range,
10805                    diagnostic: Diagnostic {
10806                        source: diagnostic.source.clone(),
10807                        source_kind,
10808                        code: diagnostic.code.clone(),
10809                        code_description: diagnostic
10810                            .code_description
10811                            .as_ref()
10812                            .and_then(|d| d.href.clone()),
10813                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10814                        markdown: adapter.as_ref().and_then(|adapter| {
10815                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10816                        }),
10817                        message: diagnostic.message.trim().to_string(),
10818                        group_id,
10819                        is_primary: true,
10820                        is_disk_based,
10821                        is_unnecessary,
10822                        underline,
10823                        data: diagnostic.data.clone(),
10824                    },
10825                });
10826                if let Some(infos) = &diagnostic.related_information {
10827                    for info in infos {
10828                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10829                            let range = range_from_lsp(info.location.range);
10830                            diagnostics.push(DiagnosticEntry {
10831                                range,
10832                                diagnostic: Diagnostic {
10833                                    source: diagnostic.source.clone(),
10834                                    source_kind,
10835                                    code: diagnostic.code.clone(),
10836                                    code_description: diagnostic
10837                                        .code_description
10838                                        .as_ref()
10839                                        .and_then(|d| d.href.clone()),
10840                                    severity: DiagnosticSeverity::INFORMATION,
10841                                    markdown: adapter.as_ref().and_then(|adapter| {
10842                                        adapter.diagnostic_message_to_markdown(&info.message)
10843                                    }),
10844                                    message: info.message.trim().to_string(),
10845                                    group_id,
10846                                    is_primary: false,
10847                                    is_disk_based,
10848                                    is_unnecessary: false,
10849                                    underline,
10850                                    data: diagnostic.data.clone(),
10851                                },
10852                            });
10853                        }
10854                    }
10855                }
10856            }
10857        }
10858
10859        for entry in &mut diagnostics {
10860            let diagnostic = &mut entry.diagnostic;
10861            if !diagnostic.is_primary {
10862                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10863                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10864                    source,
10865                    diagnostic.code.clone(),
10866                    entry.range.clone(),
10867                )) {
10868                    if let Some(severity) = severity {
10869                        diagnostic.severity = severity;
10870                    }
10871                    diagnostic.is_unnecessary = is_unnecessary;
10872                }
10873            }
10874        }
10875
10876        DocumentDiagnostics {
10877            diagnostics,
10878            document_abs_path,
10879            version: lsp_diagnostics.version,
10880        }
10881    }
10882
10883    fn insert_newly_running_language_server(
10884        &mut self,
10885        adapter: Arc<CachedLspAdapter>,
10886        language_server: Arc<LanguageServer>,
10887        server_id: LanguageServerId,
10888        key: LanguageServerSeed,
10889        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10890        cx: &mut Context<Self>,
10891    ) {
10892        let Some(local) = self.as_local_mut() else {
10893            return;
10894        };
10895        // If the language server for this key doesn't match the server id, don't store the
10896        // server. Which will cause it to be dropped, killing the process
10897        if local
10898            .language_server_ids
10899            .get(&key)
10900            .map(|state| state.id != server_id)
10901            .unwrap_or(false)
10902        {
10903            return;
10904        }
10905
10906        // Update language_servers collection with Running variant of LanguageServerState
10907        // indicating that the server is up and running and ready
10908        let workspace_folders = workspace_folders.lock().clone();
10909        language_server.set_workspace_folders(workspace_folders);
10910
10911        local.language_servers.insert(
10912            server_id,
10913            LanguageServerState::Running {
10914                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10915                    language_server.clone(),
10916                    cx,
10917                ),
10918                adapter: adapter.clone(),
10919                server: language_server.clone(),
10920                simulate_disk_based_diagnostics_completion: None,
10921            },
10922        );
10923        local
10924            .languages
10925            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10926        if let Some(file_ops_caps) = language_server
10927            .capabilities()
10928            .workspace
10929            .as_ref()
10930            .and_then(|ws| ws.file_operations.as_ref())
10931        {
10932            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10933            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10934            if did_rename_caps.or(will_rename_caps).is_some() {
10935                let watcher = RenamePathsWatchedForServer::default()
10936                    .with_did_rename_patterns(did_rename_caps)
10937                    .with_will_rename_patterns(will_rename_caps);
10938                local
10939                    .language_server_paths_watched_for_rename
10940                    .insert(server_id, watcher);
10941            }
10942        }
10943
10944        self.language_server_statuses.insert(
10945            server_id,
10946            LanguageServerStatus {
10947                name: language_server.name(),
10948                pending_work: Default::default(),
10949                has_pending_diagnostic_updates: false,
10950                progress_tokens: Default::default(),
10951                worktree: Some(key.worktree_id),
10952            },
10953        );
10954
10955        cx.emit(LspStoreEvent::LanguageServerAdded(
10956            server_id,
10957            language_server.name(),
10958            Some(key.worktree_id),
10959        ));
10960        cx.emit(LspStoreEvent::RefreshInlayHints);
10961
10962        let server_capabilities = language_server.capabilities();
10963        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10964            downstream_client
10965                .send(proto::StartLanguageServer {
10966                    project_id: *project_id,
10967                    server: Some(proto::LanguageServer {
10968                        id: server_id.to_proto(),
10969                        name: language_server.name().to_string(),
10970                        worktree_id: Some(key.worktree_id.to_proto()),
10971                    }),
10972                    capabilities: serde_json::to_string(&server_capabilities)
10973                        .expect("serializing server LSP capabilities"),
10974                })
10975                .log_err();
10976        }
10977        self.lsp_server_capabilities
10978            .insert(server_id, server_capabilities);
10979
10980        // Tell the language server about every open buffer in the worktree that matches the language.
10981        // Also check for buffers in worktrees that reused this server
10982        let mut worktrees_using_server = vec![key.worktree_id];
10983        if let Some(local) = self.as_local() {
10984            // Find all worktrees that have this server in their language server tree
10985            for (worktree_id, servers) in &local.lsp_tree.instances {
10986                if *worktree_id != key.worktree_id {
10987                    for server_map in servers.roots.values() {
10988                        if server_map.contains_key(&key.name) {
10989                            worktrees_using_server.push(*worktree_id);
10990                        }
10991                    }
10992                }
10993            }
10994        }
10995
10996        let mut buffer_paths_registered = Vec::new();
10997        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10998            for buffer_handle in buffer_store.buffers() {
10999                let buffer = buffer_handle.read(cx);
11000                let file = match File::from_dyn(buffer.file()) {
11001                    Some(file) => file,
11002                    None => continue,
11003                };
11004                let language = match buffer.language() {
11005                    Some(language) => language,
11006                    None => continue,
11007                };
11008
11009                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11010                    || !self
11011                        .languages
11012                        .lsp_adapters(&language.name())
11013                        .iter()
11014                        .any(|a| a.name == key.name)
11015                {
11016                    continue;
11017                }
11018                // didOpen
11019                let file = match file.as_local() {
11020                    Some(file) => file,
11021                    None => continue,
11022                };
11023
11024                let local = self.as_local_mut().unwrap();
11025
11026                let buffer_id = buffer.remote_id();
11027                if local.registered_buffers.contains_key(&buffer_id) {
11028                    let versions = local
11029                        .buffer_snapshots
11030                        .entry(buffer_id)
11031                        .or_default()
11032                        .entry(server_id)
11033                        .and_modify(|_| {
11034                            assert!(
11035                            false,
11036                            "There should not be an existing snapshot for a newly inserted buffer"
11037                        )
11038                        })
11039                        .or_insert_with(|| {
11040                            vec![LspBufferSnapshot {
11041                                version: 0,
11042                                snapshot: buffer.text_snapshot(),
11043                            }]
11044                        });
11045
11046                    let snapshot = versions.last().unwrap();
11047                    let version = snapshot.version;
11048                    let initial_snapshot = &snapshot.snapshot;
11049                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11050                    language_server.register_buffer(
11051                        uri,
11052                        adapter.language_id(&language.name()),
11053                        version,
11054                        initial_snapshot.text(),
11055                    );
11056                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11057                    local
11058                        .buffers_opened_in_servers
11059                        .entry(buffer_id)
11060                        .or_default()
11061                        .insert(server_id);
11062                }
11063                buffer_handle.update(cx, |buffer, cx| {
11064                    buffer.set_completion_triggers(
11065                        server_id,
11066                        language_server
11067                            .capabilities()
11068                            .completion_provider
11069                            .as_ref()
11070                            .and_then(|provider| {
11071                                provider
11072                                    .trigger_characters
11073                                    .as_ref()
11074                                    .map(|characters| characters.iter().cloned().collect())
11075                            })
11076                            .unwrap_or_default(),
11077                        cx,
11078                    )
11079                });
11080            }
11081        });
11082
11083        for (buffer_id, abs_path) in buffer_paths_registered {
11084            cx.emit(LspStoreEvent::LanguageServerUpdate {
11085                language_server_id: server_id,
11086                name: Some(adapter.name()),
11087                message: proto::update_language_server::Variant::RegisteredForBuffer(
11088                    proto::RegisteredForBuffer {
11089                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
11090                        buffer_id: buffer_id.to_proto(),
11091                    },
11092                ),
11093            });
11094        }
11095
11096        cx.notify();
11097    }
11098
11099    pub fn language_servers_running_disk_based_diagnostics(
11100        &self,
11101    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11102        self.language_server_statuses
11103            .iter()
11104            .filter_map(|(id, status)| {
11105                if status.has_pending_diagnostic_updates {
11106                    Some(*id)
11107                } else {
11108                    None
11109                }
11110            })
11111    }
11112
11113    pub(crate) fn cancel_language_server_work_for_buffers(
11114        &mut self,
11115        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11116        cx: &mut Context<Self>,
11117    ) {
11118        if let Some((client, project_id)) = self.upstream_client() {
11119            let request = client.request(proto::CancelLanguageServerWork {
11120                project_id,
11121                work: Some(proto::cancel_language_server_work::Work::Buffers(
11122                    proto::cancel_language_server_work::Buffers {
11123                        buffer_ids: buffers
11124                            .into_iter()
11125                            .map(|b| b.read(cx).remote_id().to_proto())
11126                            .collect(),
11127                    },
11128                )),
11129            });
11130            cx.background_spawn(request).detach_and_log_err(cx);
11131        } else if let Some(local) = self.as_local() {
11132            let servers = buffers
11133                .into_iter()
11134                .flat_map(|buffer| {
11135                    buffer.update(cx, |buffer, cx| {
11136                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11137                    })
11138                })
11139                .collect::<HashSet<_>>();
11140            for server_id in servers {
11141                self.cancel_language_server_work(server_id, None, cx);
11142            }
11143        }
11144    }
11145
11146    pub(crate) fn cancel_language_server_work(
11147        &mut self,
11148        server_id: LanguageServerId,
11149        token_to_cancel: Option<String>,
11150        cx: &mut Context<Self>,
11151    ) {
11152        if let Some(local) = self.as_local() {
11153            let status = self.language_server_statuses.get(&server_id);
11154            let server = local.language_servers.get(&server_id);
11155            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11156            {
11157                for (token, progress) in &status.pending_work {
11158                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11159                        && token != token_to_cancel
11160                    {
11161                        continue;
11162                    }
11163                    if progress.is_cancellable {
11164                        server
11165                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11166                                &WorkDoneProgressCancelParams {
11167                                    token: lsp::NumberOrString::String(token.clone()),
11168                                },
11169                            )
11170                            .ok();
11171                    }
11172                }
11173            }
11174        } else if let Some((client, project_id)) = self.upstream_client() {
11175            let request = client.request(proto::CancelLanguageServerWork {
11176                project_id,
11177                work: Some(
11178                    proto::cancel_language_server_work::Work::LanguageServerWork(
11179                        proto::cancel_language_server_work::LanguageServerWork {
11180                            language_server_id: server_id.to_proto(),
11181                            token: token_to_cancel,
11182                        },
11183                    ),
11184                ),
11185            });
11186            cx.background_spawn(request).detach_and_log_err(cx);
11187        }
11188    }
11189
11190    fn register_supplementary_language_server(
11191        &mut self,
11192        id: LanguageServerId,
11193        name: LanguageServerName,
11194        server: Arc<LanguageServer>,
11195        cx: &mut Context<Self>,
11196    ) {
11197        if let Some(local) = self.as_local_mut() {
11198            local
11199                .supplementary_language_servers
11200                .insert(id, (name.clone(), server));
11201            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11202        }
11203    }
11204
11205    fn unregister_supplementary_language_server(
11206        &mut self,
11207        id: LanguageServerId,
11208        cx: &mut Context<Self>,
11209    ) {
11210        if let Some(local) = self.as_local_mut() {
11211            local.supplementary_language_servers.remove(&id);
11212            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11213        }
11214    }
11215
11216    pub(crate) fn supplementary_language_servers(
11217        &self,
11218    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11219        self.as_local().into_iter().flat_map(|local| {
11220            local
11221                .supplementary_language_servers
11222                .iter()
11223                .map(|(id, (name, _))| (*id, name.clone()))
11224        })
11225    }
11226
11227    pub fn language_server_adapter_for_id(
11228        &self,
11229        id: LanguageServerId,
11230    ) -> Option<Arc<CachedLspAdapter>> {
11231        self.as_local()
11232            .and_then(|local| local.language_servers.get(&id))
11233            .and_then(|language_server_state| match language_server_state {
11234                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11235                _ => None,
11236            })
11237    }
11238
11239    pub(super) fn update_local_worktree_language_servers(
11240        &mut self,
11241        worktree_handle: &Entity<Worktree>,
11242        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
11243        cx: &mut Context<Self>,
11244    ) {
11245        if changes.is_empty() {
11246            return;
11247        }
11248
11249        let Some(local) = self.as_local() else { return };
11250
11251        local.prettier_store.update(cx, |prettier_store, cx| {
11252            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11253        });
11254
11255        let worktree_id = worktree_handle.read(cx).id();
11256        let mut language_server_ids = local
11257            .language_server_ids
11258            .iter()
11259            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11260            .collect::<Vec<_>>();
11261        language_server_ids.sort();
11262        language_server_ids.dedup();
11263
11264        let abs_path = worktree_handle.read(cx).abs_path();
11265        for server_id in &language_server_ids {
11266            if let Some(LanguageServerState::Running { server, .. }) =
11267                local.language_servers.get(server_id)
11268                && let Some(watched_paths) = local
11269                    .language_server_watched_paths
11270                    .get(server_id)
11271                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11272            {
11273                let params = lsp::DidChangeWatchedFilesParams {
11274                    changes: changes
11275                        .iter()
11276                        .filter_map(|(path, _, change)| {
11277                            if !watched_paths.is_match(path) {
11278                                return None;
11279                            }
11280                            let typ = match change {
11281                                PathChange::Loaded => return None,
11282                                PathChange::Added => lsp::FileChangeType::CREATED,
11283                                PathChange::Removed => lsp::FileChangeType::DELETED,
11284                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11285                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11286                            };
11287                            Some(lsp::FileEvent {
11288                                uri: lsp::Uri::from_file_path(abs_path.join(path)).unwrap(),
11289                                typ,
11290                            })
11291                        })
11292                        .collect(),
11293                };
11294                if !params.changes.is_empty() {
11295                    server
11296                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
11297                        .ok();
11298                }
11299            }
11300        }
11301        for (path, _, _) in changes {
11302            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
11303                && local.watched_manifest_filenames.contains(file_name)
11304            {
11305                self.request_workspace_config_refresh();
11306                break;
11307            }
11308        }
11309    }
11310
11311    pub fn wait_for_remote_buffer(
11312        &mut self,
11313        id: BufferId,
11314        cx: &mut Context<Self>,
11315    ) -> Task<Result<Entity<Buffer>>> {
11316        self.buffer_store.update(cx, |buffer_store, cx| {
11317            buffer_store.wait_for_remote_buffer(id, cx)
11318        })
11319    }
11320
11321    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11322        proto::Symbol {
11323            language_server_name: symbol.language_server_name.0.to_string(),
11324            source_worktree_id: symbol.source_worktree_id.to_proto(),
11325            language_server_id: symbol.source_language_server_id.to_proto(),
11326            worktree_id: symbol.path.worktree_id.to_proto(),
11327            path: symbol.path.path.as_ref().to_proto(),
11328            name: symbol.name.clone(),
11329            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11330            start: Some(proto::PointUtf16 {
11331                row: symbol.range.start.0.row,
11332                column: symbol.range.start.0.column,
11333            }),
11334            end: Some(proto::PointUtf16 {
11335                row: symbol.range.end.0.row,
11336                column: symbol.range.end.0.column,
11337            }),
11338            signature: symbol.signature.to_vec(),
11339        }
11340    }
11341
11342    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11343        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11344        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11345        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11346        let path = ProjectPath {
11347            worktree_id,
11348            path: Arc::<Path>::from_proto(serialized_symbol.path),
11349        };
11350
11351        let start = serialized_symbol.start.context("invalid start")?;
11352        let end = serialized_symbol.end.context("invalid end")?;
11353        Ok(CoreSymbol {
11354            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11355            source_worktree_id,
11356            source_language_server_id: LanguageServerId::from_proto(
11357                serialized_symbol.language_server_id,
11358            ),
11359            path,
11360            name: serialized_symbol.name,
11361            range: Unclipped(PointUtf16::new(start.row, start.column))
11362                ..Unclipped(PointUtf16::new(end.row, end.column)),
11363            kind,
11364            signature: serialized_symbol
11365                .signature
11366                .try_into()
11367                .map_err(|_| anyhow!("invalid signature"))?,
11368        })
11369    }
11370
11371    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11372        let mut serialized_completion = proto::Completion {
11373            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11374            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11375            new_text: completion.new_text.clone(),
11376            ..proto::Completion::default()
11377        };
11378        match &completion.source {
11379            CompletionSource::Lsp {
11380                insert_range,
11381                server_id,
11382                lsp_completion,
11383                lsp_defaults,
11384                resolved,
11385            } => {
11386                let (old_insert_start, old_insert_end) = insert_range
11387                    .as_ref()
11388                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11389                    .unzip();
11390
11391                serialized_completion.old_insert_start = old_insert_start;
11392                serialized_completion.old_insert_end = old_insert_end;
11393                serialized_completion.source = proto::completion::Source::Lsp as i32;
11394                serialized_completion.server_id = server_id.0 as u64;
11395                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11396                serialized_completion.lsp_defaults = lsp_defaults
11397                    .as_deref()
11398                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11399                serialized_completion.resolved = *resolved;
11400            }
11401            CompletionSource::BufferWord {
11402                word_range,
11403                resolved,
11404            } => {
11405                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11406                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11407                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11408                serialized_completion.resolved = *resolved;
11409            }
11410            CompletionSource::Custom => {
11411                serialized_completion.source = proto::completion::Source::Custom as i32;
11412                serialized_completion.resolved = true;
11413            }
11414            CompletionSource::Dap { sort_text } => {
11415                serialized_completion.source = proto::completion::Source::Dap as i32;
11416                serialized_completion.sort_text = Some(sort_text.clone());
11417            }
11418        }
11419
11420        serialized_completion
11421    }
11422
11423    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11424        let old_replace_start = completion
11425            .old_replace_start
11426            .and_then(deserialize_anchor)
11427            .context("invalid old start")?;
11428        let old_replace_end = completion
11429            .old_replace_end
11430            .and_then(deserialize_anchor)
11431            .context("invalid old end")?;
11432        let insert_range = {
11433            match completion.old_insert_start.zip(completion.old_insert_end) {
11434                Some((start, end)) => {
11435                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11436                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11437                    Some(start..end)
11438                }
11439                None => None,
11440            }
11441        };
11442        Ok(CoreCompletion {
11443            replace_range: old_replace_start..old_replace_end,
11444            new_text: completion.new_text,
11445            source: match proto::completion::Source::from_i32(completion.source) {
11446                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11447                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11448                    insert_range,
11449                    server_id: LanguageServerId::from_proto(completion.server_id),
11450                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11451                    lsp_defaults: completion
11452                        .lsp_defaults
11453                        .as_deref()
11454                        .map(serde_json::from_slice)
11455                        .transpose()?,
11456                    resolved: completion.resolved,
11457                },
11458                Some(proto::completion::Source::BufferWord) => {
11459                    let word_range = completion
11460                        .buffer_word_start
11461                        .and_then(deserialize_anchor)
11462                        .context("invalid buffer word start")?
11463                        ..completion
11464                            .buffer_word_end
11465                            .and_then(deserialize_anchor)
11466                            .context("invalid buffer word end")?;
11467                    CompletionSource::BufferWord {
11468                        word_range,
11469                        resolved: completion.resolved,
11470                    }
11471                }
11472                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11473                    sort_text: completion
11474                        .sort_text
11475                        .context("expected sort text to exist")?,
11476                },
11477                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11478            },
11479        })
11480    }
11481
11482    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11483        let (kind, lsp_action) = match &action.lsp_action {
11484            LspAction::Action(code_action) => (
11485                proto::code_action::Kind::Action as i32,
11486                serde_json::to_vec(code_action).unwrap(),
11487            ),
11488            LspAction::Command(command) => (
11489                proto::code_action::Kind::Command as i32,
11490                serde_json::to_vec(command).unwrap(),
11491            ),
11492            LspAction::CodeLens(code_lens) => (
11493                proto::code_action::Kind::CodeLens as i32,
11494                serde_json::to_vec(code_lens).unwrap(),
11495            ),
11496        };
11497
11498        proto::CodeAction {
11499            server_id: action.server_id.0 as u64,
11500            start: Some(serialize_anchor(&action.range.start)),
11501            end: Some(serialize_anchor(&action.range.end)),
11502            lsp_action,
11503            kind,
11504            resolved: action.resolved,
11505        }
11506    }
11507
11508    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11509        let start = action
11510            .start
11511            .and_then(deserialize_anchor)
11512            .context("invalid start")?;
11513        let end = action
11514            .end
11515            .and_then(deserialize_anchor)
11516            .context("invalid end")?;
11517        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11518            Some(proto::code_action::Kind::Action) => {
11519                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11520            }
11521            Some(proto::code_action::Kind::Command) => {
11522                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11523            }
11524            Some(proto::code_action::Kind::CodeLens) => {
11525                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11526            }
11527            None => anyhow::bail!("Unknown action kind {}", action.kind),
11528        };
11529        Ok(CodeAction {
11530            server_id: LanguageServerId(action.server_id as usize),
11531            range: start..end,
11532            resolved: action.resolved,
11533            lsp_action,
11534        })
11535    }
11536
11537    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11538        match &formatting_result {
11539            Ok(_) => self.last_formatting_failure = None,
11540            Err(error) => {
11541                let error_string = format!("{error:#}");
11542                log::error!("Formatting failed: {error_string}");
11543                self.last_formatting_failure
11544                    .replace(error_string.lines().join(" "));
11545            }
11546        }
11547    }
11548
11549    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11550        self.lsp_server_capabilities.remove(&for_server);
11551        for buffer_colors in self.lsp_document_colors.values_mut() {
11552            buffer_colors.colors.remove(&for_server);
11553            buffer_colors.cache_version += 1;
11554        }
11555        for buffer_lens in self.lsp_code_lens.values_mut() {
11556            buffer_lens.lens.remove(&for_server);
11557        }
11558        if let Some(local) = self.as_local_mut() {
11559            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11560            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11561                buffer_servers.remove(&for_server);
11562            }
11563        }
11564    }
11565
11566    pub fn result_id(
11567        &self,
11568        server_id: LanguageServerId,
11569        buffer_id: BufferId,
11570        cx: &App,
11571    ) -> Option<String> {
11572        let abs_path = self
11573            .buffer_store
11574            .read(cx)
11575            .get(buffer_id)
11576            .and_then(|b| File::from_dyn(b.read(cx).file()))
11577            .map(|f| f.abs_path(cx))?;
11578        self.as_local()?
11579            .buffer_pull_diagnostics_result_ids
11580            .get(&server_id)?
11581            .get(&abs_path)?
11582            .clone()
11583    }
11584
11585    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11586        let Some(local) = self.as_local() else {
11587            return HashMap::default();
11588        };
11589        local
11590            .buffer_pull_diagnostics_result_ids
11591            .get(&server_id)
11592            .into_iter()
11593            .flatten()
11594            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11595            .collect()
11596    }
11597
11598    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11599        if let Some(LanguageServerState::Running {
11600            workspace_refresh_task: Some(workspace_refresh_task),
11601            ..
11602        }) = self
11603            .as_local_mut()
11604            .and_then(|local| local.language_servers.get_mut(&server_id))
11605        {
11606            workspace_refresh_task.refresh_tx.try_send(()).ok();
11607        }
11608    }
11609
11610    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11611        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11612            return;
11613        };
11614        let Some(local) = self.as_local_mut() else {
11615            return;
11616        };
11617
11618        for server_id in buffer.update(cx, |buffer, cx| {
11619            local.language_server_ids_for_buffer(buffer, cx)
11620        }) {
11621            if let Some(LanguageServerState::Running {
11622                workspace_refresh_task: Some(workspace_refresh_task),
11623                ..
11624            }) = local.language_servers.get_mut(&server_id)
11625            {
11626                workspace_refresh_task.refresh_tx.try_send(()).ok();
11627            }
11628        }
11629    }
11630
11631    fn apply_workspace_diagnostic_report(
11632        &mut self,
11633        server_id: LanguageServerId,
11634        report: lsp::WorkspaceDiagnosticReportResult,
11635        cx: &mut Context<Self>,
11636    ) {
11637        let workspace_diagnostics =
11638            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11639        let mut unchanged_buffers = HashSet::default();
11640        let mut changed_buffers = HashSet::default();
11641        let workspace_diagnostics_updates = workspace_diagnostics
11642            .into_iter()
11643            .filter_map(
11644                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11645                    LspPullDiagnostics::Response {
11646                        server_id,
11647                        uri,
11648                        diagnostics,
11649                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11650                    LspPullDiagnostics::Default => None,
11651                },
11652            )
11653            .fold(
11654                HashMap::default(),
11655                |mut acc, (server_id, uri, diagnostics, version)| {
11656                    let (result_id, diagnostics) = match diagnostics {
11657                        PulledDiagnostics::Unchanged { result_id } => {
11658                            unchanged_buffers.insert(uri.clone());
11659                            (Some(result_id), Vec::new())
11660                        }
11661                        PulledDiagnostics::Changed {
11662                            result_id,
11663                            diagnostics,
11664                        } => {
11665                            changed_buffers.insert(uri.clone());
11666                            (result_id, diagnostics)
11667                        }
11668                    };
11669                    let disk_based_sources = Cow::Owned(
11670                        self.language_server_adapter_for_id(server_id)
11671                            .as_ref()
11672                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11673                            .unwrap_or(&[])
11674                            .to_vec(),
11675                    );
11676                    acc.entry(server_id)
11677                        .or_insert_with(Vec::new)
11678                        .push(DocumentDiagnosticsUpdate {
11679                            server_id,
11680                            diagnostics: lsp::PublishDiagnosticsParams {
11681                                uri,
11682                                diagnostics,
11683                                version,
11684                            },
11685                            result_id,
11686                            disk_based_sources,
11687                        });
11688                    acc
11689                },
11690            );
11691
11692        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11693            self.merge_lsp_diagnostics(
11694                DiagnosticSourceKind::Pulled,
11695                diagnostic_updates,
11696                |buffer, old_diagnostic, cx| {
11697                    File::from_dyn(buffer.file())
11698                        .and_then(|file| {
11699                            let abs_path = file.as_local()?.abs_path(cx);
11700                            lsp::Uri::from_file_path(abs_path).ok()
11701                        })
11702                        .is_none_or(|buffer_uri| {
11703                            unchanged_buffers.contains(&buffer_uri)
11704                                || match old_diagnostic.source_kind {
11705                                    DiagnosticSourceKind::Pulled => {
11706                                        !changed_buffers.contains(&buffer_uri)
11707                                    }
11708                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11709                                        true
11710                                    }
11711                                }
11712                        })
11713                },
11714                cx,
11715            )
11716            .log_err();
11717        }
11718    }
11719
11720    fn register_server_capabilities(
11721        &mut self,
11722        server_id: LanguageServerId,
11723        params: lsp::RegistrationParams,
11724        cx: &mut Context<Self>,
11725    ) -> anyhow::Result<()> {
11726        let server = self
11727            .language_server_for_id(server_id)
11728            .with_context(|| format!("no server {server_id} found"))?;
11729        for reg in params.registrations {
11730            match reg.method.as_str() {
11731                "workspace/didChangeWatchedFiles" => {
11732                    if let Some(options) = reg.register_options {
11733                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11734                            let caps = serde_json::from_value(options)?;
11735                            local_lsp_store
11736                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11737                            true
11738                        } else {
11739                            false
11740                        };
11741                        if notify {
11742                            notify_server_capabilities_updated(&server, cx);
11743                        }
11744                    }
11745                }
11746                "workspace/didChangeConfiguration" => {
11747                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11748                }
11749                "workspace/didChangeWorkspaceFolders" => {
11750                    // In this case register options is an empty object, we can ignore it
11751                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11752                        supported: Some(true),
11753                        change_notifications: Some(OneOf::Right(reg.id)),
11754                    };
11755                    server.update_capabilities(|capabilities| {
11756                        capabilities
11757                            .workspace
11758                            .get_or_insert_default()
11759                            .workspace_folders = Some(caps);
11760                    });
11761                    notify_server_capabilities_updated(&server, cx);
11762                }
11763                "workspace/symbol" => {
11764                    let options = parse_register_capabilities(reg)?;
11765                    server.update_capabilities(|capabilities| {
11766                        capabilities.workspace_symbol_provider = Some(options);
11767                    });
11768                    notify_server_capabilities_updated(&server, cx);
11769                }
11770                "workspace/fileOperations" => {
11771                    if let Some(options) = reg.register_options {
11772                        let caps = serde_json::from_value(options)?;
11773                        server.update_capabilities(|capabilities| {
11774                            capabilities
11775                                .workspace
11776                                .get_or_insert_default()
11777                                .file_operations = Some(caps);
11778                        });
11779                        notify_server_capabilities_updated(&server, cx);
11780                    }
11781                }
11782                "workspace/executeCommand" => {
11783                    if let Some(options) = reg.register_options {
11784                        let options = serde_json::from_value(options)?;
11785                        server.update_capabilities(|capabilities| {
11786                            capabilities.execute_command_provider = Some(options);
11787                        });
11788                        notify_server_capabilities_updated(&server, cx);
11789                    }
11790                }
11791                "textDocument/rangeFormatting" => {
11792                    let options = parse_register_capabilities(reg)?;
11793                    server.update_capabilities(|capabilities| {
11794                        capabilities.document_range_formatting_provider = Some(options);
11795                    });
11796                    notify_server_capabilities_updated(&server, cx);
11797                }
11798                "textDocument/onTypeFormatting" => {
11799                    if let Some(options) = reg
11800                        .register_options
11801                        .map(serde_json::from_value)
11802                        .transpose()?
11803                    {
11804                        server.update_capabilities(|capabilities| {
11805                            capabilities.document_on_type_formatting_provider = Some(options);
11806                        });
11807                        notify_server_capabilities_updated(&server, cx);
11808                    }
11809                }
11810                "textDocument/formatting" => {
11811                    let options = parse_register_capabilities(reg)?;
11812                    server.update_capabilities(|capabilities| {
11813                        capabilities.document_formatting_provider = Some(options);
11814                    });
11815                    notify_server_capabilities_updated(&server, cx);
11816                }
11817                "textDocument/rename" => {
11818                    let options = parse_register_capabilities(reg)?;
11819                    server.update_capabilities(|capabilities| {
11820                        capabilities.rename_provider = Some(options);
11821                    });
11822                    notify_server_capabilities_updated(&server, cx);
11823                }
11824                "textDocument/inlayHint" => {
11825                    let options = parse_register_capabilities(reg)?;
11826                    server.update_capabilities(|capabilities| {
11827                        capabilities.inlay_hint_provider = Some(options);
11828                    });
11829                    notify_server_capabilities_updated(&server, cx);
11830                }
11831                "textDocument/documentSymbol" => {
11832                    let options = parse_register_capabilities(reg)?;
11833                    server.update_capabilities(|capabilities| {
11834                        capabilities.document_symbol_provider = Some(options);
11835                    });
11836                    notify_server_capabilities_updated(&server, cx);
11837                }
11838                "textDocument/codeAction" => {
11839                    let options = parse_register_capabilities(reg)?;
11840                    let provider = match options {
11841                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11842                        OneOf::Right(caps) => caps,
11843                    };
11844                    server.update_capabilities(|capabilities| {
11845                        capabilities.code_action_provider = Some(provider);
11846                    });
11847                    notify_server_capabilities_updated(&server, cx);
11848                }
11849                "textDocument/definition" => {
11850                    let options = parse_register_capabilities(reg)?;
11851                    server.update_capabilities(|capabilities| {
11852                        capabilities.definition_provider = Some(options);
11853                    });
11854                    notify_server_capabilities_updated(&server, cx);
11855                }
11856                "textDocument/completion" => {
11857                    if let Some(caps) = reg
11858                        .register_options
11859                        .map(serde_json::from_value)
11860                        .transpose()?
11861                    {
11862                        server.update_capabilities(|capabilities| {
11863                            capabilities.completion_provider = Some(caps);
11864                        });
11865                        notify_server_capabilities_updated(&server, cx);
11866                    }
11867                }
11868                "textDocument/hover" => {
11869                    let options = parse_register_capabilities(reg)?;
11870                    let provider = match options {
11871                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11872                        OneOf::Right(caps) => caps,
11873                    };
11874                    server.update_capabilities(|capabilities| {
11875                        capabilities.hover_provider = Some(provider);
11876                    });
11877                    notify_server_capabilities_updated(&server, cx);
11878                }
11879                "textDocument/signatureHelp" => {
11880                    if let Some(caps) = reg
11881                        .register_options
11882                        .map(serde_json::from_value)
11883                        .transpose()?
11884                    {
11885                        server.update_capabilities(|capabilities| {
11886                            capabilities.signature_help_provider = Some(caps);
11887                        });
11888                        notify_server_capabilities_updated(&server, cx);
11889                    }
11890                }
11891                "textDocument/didChange" => {
11892                    if let Some(sync_kind) = reg
11893                        .register_options
11894                        .and_then(|opts| opts.get("syncKind").cloned())
11895                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11896                        .transpose()?
11897                    {
11898                        server.update_capabilities(|capabilities| {
11899                            let mut sync_options =
11900                                Self::take_text_document_sync_options(capabilities);
11901                            sync_options.change = Some(sync_kind);
11902                            capabilities.text_document_sync =
11903                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11904                        });
11905                        notify_server_capabilities_updated(&server, cx);
11906                    }
11907                }
11908                "textDocument/didSave" => {
11909                    if let Some(include_text) = reg
11910                        .register_options
11911                        .map(|opts| {
11912                            let transpose = opts
11913                                .get("includeText")
11914                                .cloned()
11915                                .map(serde_json::from_value::<Option<bool>>)
11916                                .transpose();
11917                            match transpose {
11918                                Ok(value) => Ok(value.flatten()),
11919                                Err(e) => Err(e),
11920                            }
11921                        })
11922                        .transpose()?
11923                    {
11924                        server.update_capabilities(|capabilities| {
11925                            let mut sync_options =
11926                                Self::take_text_document_sync_options(capabilities);
11927                            sync_options.save =
11928                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11929                                    include_text,
11930                                }));
11931                            capabilities.text_document_sync =
11932                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11933                        });
11934                        notify_server_capabilities_updated(&server, cx);
11935                    }
11936                }
11937                "textDocument/codeLens" => {
11938                    if let Some(caps) = reg
11939                        .register_options
11940                        .map(serde_json::from_value)
11941                        .transpose()?
11942                    {
11943                        server.update_capabilities(|capabilities| {
11944                            capabilities.code_lens_provider = Some(caps);
11945                        });
11946                        notify_server_capabilities_updated(&server, cx);
11947                    }
11948                }
11949                "textDocument/diagnostic" => {
11950                    if let Some(caps) = reg
11951                        .register_options
11952                        .map(serde_json::from_value)
11953                        .transpose()?
11954                    {
11955                        server.update_capabilities(|capabilities| {
11956                            capabilities.diagnostic_provider = Some(caps);
11957                        });
11958                        notify_server_capabilities_updated(&server, cx);
11959                    }
11960                }
11961                "textDocument/documentColor" => {
11962                    let options = parse_register_capabilities(reg)?;
11963                    let provider = match options {
11964                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11965                        OneOf::Right(caps) => caps,
11966                    };
11967                    server.update_capabilities(|capabilities| {
11968                        capabilities.color_provider = Some(provider);
11969                    });
11970                    notify_server_capabilities_updated(&server, cx);
11971                }
11972                _ => log::warn!("unhandled capability registration: {reg:?}"),
11973            }
11974        }
11975
11976        Ok(())
11977    }
11978
11979    fn unregister_server_capabilities(
11980        &mut self,
11981        server_id: LanguageServerId,
11982        params: lsp::UnregistrationParams,
11983        cx: &mut Context<Self>,
11984    ) -> anyhow::Result<()> {
11985        let server = self
11986            .language_server_for_id(server_id)
11987            .with_context(|| format!("no server {server_id} found"))?;
11988        for unreg in params.unregisterations.iter() {
11989            match unreg.method.as_str() {
11990                "workspace/didChangeWatchedFiles" => {
11991                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11992                        local_lsp_store
11993                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11994                        true
11995                    } else {
11996                        false
11997                    };
11998                    if notify {
11999                        notify_server_capabilities_updated(&server, cx);
12000                    }
12001                }
12002                "workspace/didChangeConfiguration" => {
12003                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12004                }
12005                "workspace/didChangeWorkspaceFolders" => {
12006                    server.update_capabilities(|capabilities| {
12007                        capabilities
12008                            .workspace
12009                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12010                                workspace_folders: None,
12011                                file_operations: None,
12012                            })
12013                            .workspace_folders = None;
12014                    });
12015                    notify_server_capabilities_updated(&server, cx);
12016                }
12017                "workspace/symbol" => {
12018                    server.update_capabilities(|capabilities| {
12019                        capabilities.workspace_symbol_provider = None
12020                    });
12021                    notify_server_capabilities_updated(&server, cx);
12022                }
12023                "workspace/fileOperations" => {
12024                    server.update_capabilities(|capabilities| {
12025                        capabilities
12026                            .workspace
12027                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12028                                workspace_folders: None,
12029                                file_operations: None,
12030                            })
12031                            .file_operations = None;
12032                    });
12033                    notify_server_capabilities_updated(&server, cx);
12034                }
12035                "workspace/executeCommand" => {
12036                    server.update_capabilities(|capabilities| {
12037                        capabilities.execute_command_provider = None;
12038                    });
12039                    notify_server_capabilities_updated(&server, cx);
12040                }
12041                "textDocument/rangeFormatting" => {
12042                    server.update_capabilities(|capabilities| {
12043                        capabilities.document_range_formatting_provider = None
12044                    });
12045                    notify_server_capabilities_updated(&server, cx);
12046                }
12047                "textDocument/onTypeFormatting" => {
12048                    server.update_capabilities(|capabilities| {
12049                        capabilities.document_on_type_formatting_provider = None;
12050                    });
12051                    notify_server_capabilities_updated(&server, cx);
12052                }
12053                "textDocument/formatting" => {
12054                    server.update_capabilities(|capabilities| {
12055                        capabilities.document_formatting_provider = None;
12056                    });
12057                    notify_server_capabilities_updated(&server, cx);
12058                }
12059                "textDocument/rename" => {
12060                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12061                    notify_server_capabilities_updated(&server, cx);
12062                }
12063                "textDocument/codeAction" => {
12064                    server.update_capabilities(|capabilities| {
12065                        capabilities.code_action_provider = None;
12066                    });
12067                    notify_server_capabilities_updated(&server, cx);
12068                }
12069                "textDocument/definition" => {
12070                    server.update_capabilities(|capabilities| {
12071                        capabilities.definition_provider = None;
12072                    });
12073                    notify_server_capabilities_updated(&server, cx);
12074                }
12075                "textDocument/completion" => {
12076                    server.update_capabilities(|capabilities| {
12077                        capabilities.completion_provider = None;
12078                    });
12079                    notify_server_capabilities_updated(&server, cx);
12080                }
12081                "textDocument/hover" => {
12082                    server.update_capabilities(|capabilities| {
12083                        capabilities.hover_provider = None;
12084                    });
12085                    notify_server_capabilities_updated(&server, cx);
12086                }
12087                "textDocument/signatureHelp" => {
12088                    server.update_capabilities(|capabilities| {
12089                        capabilities.signature_help_provider = None;
12090                    });
12091                    notify_server_capabilities_updated(&server, cx);
12092                }
12093                "textDocument/didChange" => {
12094                    server.update_capabilities(|capabilities| {
12095                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12096                        sync_options.change = None;
12097                        capabilities.text_document_sync =
12098                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12099                    });
12100                    notify_server_capabilities_updated(&server, cx);
12101                }
12102                "textDocument/didSave" => {
12103                    server.update_capabilities(|capabilities| {
12104                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12105                        sync_options.save = None;
12106                        capabilities.text_document_sync =
12107                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12108                    });
12109                    notify_server_capabilities_updated(&server, cx);
12110                }
12111                "textDocument/codeLens" => {
12112                    server.update_capabilities(|capabilities| {
12113                        capabilities.code_lens_provider = None;
12114                    });
12115                    notify_server_capabilities_updated(&server, cx);
12116                }
12117                "textDocument/diagnostic" => {
12118                    server.update_capabilities(|capabilities| {
12119                        capabilities.diagnostic_provider = None;
12120                    });
12121                    notify_server_capabilities_updated(&server, cx);
12122                }
12123                "textDocument/documentColor" => {
12124                    server.update_capabilities(|capabilities| {
12125                        capabilities.color_provider = None;
12126                    });
12127                    notify_server_capabilities_updated(&server, cx);
12128                }
12129                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12130            }
12131        }
12132
12133        Ok(())
12134    }
12135
12136    async fn query_lsp_locally<T>(
12137        lsp_store: Entity<Self>,
12138        sender_id: proto::PeerId,
12139        lsp_request_id: LspRequestId,
12140        proto_request: T::ProtoRequest,
12141        position: Option<Anchor>,
12142        mut cx: AsyncApp,
12143    ) -> Result<()>
12144    where
12145        T: LspCommand + Clone,
12146        T::ProtoRequest: proto::LspRequestMessage,
12147        <T::ProtoRequest as proto::RequestMessage>::Response:
12148            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12149    {
12150        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12151        let version = deserialize_version(proto_request.buffer_version());
12152        let buffer = lsp_store.update(&mut cx, |this, cx| {
12153            this.buffer_store.read(cx).get_existing(buffer_id)
12154        })??;
12155        buffer
12156            .update(&mut cx, |buffer, _| {
12157                buffer.wait_for_version(version.clone())
12158            })?
12159            .await?;
12160        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
12161        let request =
12162            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12163        lsp_store.update(&mut cx, |lsp_store, cx| {
12164            let request_task =
12165                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
12166            let existing_queries = lsp_store
12167                .running_lsp_requests
12168                .entry(TypeId::of::<T>())
12169                .or_default();
12170            if T::ProtoRequest::stop_previous_requests()
12171                || buffer_version.changed_since(&existing_queries.0)
12172            {
12173                existing_queries.1.clear();
12174            }
12175            existing_queries.1.insert(
12176                lsp_request_id,
12177                cx.spawn(async move |lsp_store, cx| {
12178                    let response = request_task.await;
12179                    lsp_store
12180                        .update(cx, |lsp_store, cx| {
12181                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12182                            {
12183                                let response = response
12184                                    .into_iter()
12185                                    .map(|(server_id, response)| {
12186                                        (
12187                                            server_id.to_proto(),
12188                                            T::response_to_proto(
12189                                                response,
12190                                                lsp_store,
12191                                                sender_id,
12192                                                &buffer_version,
12193                                                cx,
12194                                            )
12195                                            .into(),
12196                                        )
12197                                    })
12198                                    .collect::<HashMap<_, _>>();
12199                                match client.send_lsp_response::<T::ProtoRequest>(
12200                                    project_id,
12201                                    lsp_request_id,
12202                                    response,
12203                                ) {
12204                                    Ok(()) => {}
12205                                    Err(e) => {
12206                                        log::error!("Failed to send LSP response: {e:#}",)
12207                                    }
12208                                }
12209                            }
12210                        })
12211                        .ok();
12212                }),
12213            );
12214        })?;
12215        Ok(())
12216    }
12217
12218    fn take_text_document_sync_options(
12219        capabilities: &mut lsp::ServerCapabilities,
12220    ) -> lsp::TextDocumentSyncOptions {
12221        match capabilities.text_document_sync.take() {
12222            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12223            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12224                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12225                sync_options.change = Some(sync_kind);
12226                sync_options
12227            }
12228            None => lsp::TextDocumentSyncOptions::default(),
12229        }
12230    }
12231
12232    #[cfg(any(test, feature = "test-support"))]
12233    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12234        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
12235        Some(data.update.take()?.1)
12236    }
12237
12238    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12239        self.downstream_client.clone()
12240    }
12241
12242    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12243        self.worktree_store.clone()
12244    }
12245}
12246
12247// Registration with registerOptions as null, should fallback to true.
12248// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12249fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12250    reg: lsp::Registration,
12251) -> Result<OneOf<bool, T>> {
12252    Ok(match reg.register_options {
12253        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12254        None => OneOf::Left(true),
12255    })
12256}
12257
12258fn subscribe_to_binary_statuses(
12259    languages: &Arc<LanguageRegistry>,
12260    cx: &mut Context<'_, LspStore>,
12261) -> Task<()> {
12262    let mut server_statuses = languages.language_server_binary_statuses();
12263    cx.spawn(async move |lsp_store, cx| {
12264        while let Some((server_name, binary_status)) = server_statuses.next().await {
12265            if lsp_store
12266                .update(cx, |_, cx| {
12267                    let mut message = None;
12268                    let binary_status = match binary_status {
12269                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12270                        BinaryStatus::CheckingForUpdate => {
12271                            proto::ServerBinaryStatus::CheckingForUpdate
12272                        }
12273                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12274                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12275                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12276                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12277                        BinaryStatus::Failed { error } => {
12278                            message = Some(error);
12279                            proto::ServerBinaryStatus::Failed
12280                        }
12281                    };
12282                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12283                        // Binary updates are about the binary that might not have any language server id at that point.
12284                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12285                        language_server_id: LanguageServerId(0),
12286                        name: Some(server_name),
12287                        message: proto::update_language_server::Variant::StatusUpdate(
12288                            proto::StatusUpdate {
12289                                message,
12290                                status: Some(proto::status_update::Status::Binary(
12291                                    binary_status as i32,
12292                                )),
12293                            },
12294                        ),
12295                    });
12296                })
12297                .is_err()
12298            {
12299                break;
12300            }
12301        }
12302    })
12303}
12304
12305fn lsp_workspace_diagnostics_refresh(
12306    server: Arc<LanguageServer>,
12307    cx: &mut Context<'_, LspStore>,
12308) -> Option<WorkspaceRefreshTask> {
12309    let identifier = match server.capabilities().diagnostic_provider? {
12310        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12311            if !diagnostic_options.workspace_diagnostics {
12312                return None;
12313            }
12314            diagnostic_options.identifier
12315        }
12316        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12317            let diagnostic_options = registration_options.diagnostic_options;
12318            if !diagnostic_options.workspace_diagnostics {
12319                return None;
12320            }
12321            diagnostic_options.identifier
12322        }
12323    };
12324
12325    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12326    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12327    refresh_tx.try_send(()).ok();
12328
12329    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12330        let mut attempts = 0;
12331        let max_attempts = 50;
12332        let mut requests = 0;
12333
12334        loop {
12335            let Some(()) = refresh_rx.recv().await else {
12336                return;
12337            };
12338
12339            'request: loop {
12340                requests += 1;
12341                if attempts > max_attempts {
12342                    log::error!(
12343                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12344                    );
12345                    return;
12346                }
12347                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12348                cx.background_executor()
12349                    .timer(Duration::from_millis(backoff_millis))
12350                    .await;
12351                attempts += 1;
12352
12353                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12354                    lsp_store
12355                        .all_result_ids(server.server_id())
12356                        .into_iter()
12357                        .filter_map(|(abs_path, result_id)| {
12358                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12359                            Some(lsp::PreviousResultId {
12360                                uri,
12361                                value: result_id,
12362                            })
12363                        })
12364                        .collect()
12365                }) else {
12366                    return;
12367                };
12368
12369                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12370
12371                progress_rx.try_recv().ok();
12372                let timer =
12373                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12374                let progress = pin!(progress_rx.recv().fuse());
12375                let response_result = server
12376                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12377                        lsp::WorkspaceDiagnosticParams {
12378                            previous_result_ids,
12379                            identifier: identifier.clone(),
12380                            work_done_progress_params: Default::default(),
12381                            partial_result_params: lsp::PartialResultParams {
12382                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12383                            },
12384                        },
12385                        select(timer, progress).then(|either| match either {
12386                            Either::Left((message, ..)) => ready(message).left_future(),
12387                            Either::Right(..) => pending::<String>().right_future(),
12388                        }),
12389                    )
12390                    .await;
12391
12392                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12393                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12394                match response_result {
12395                    ConnectionResult::Timeout => {
12396                        log::error!("Timeout during workspace diagnostics pull");
12397                        continue 'request;
12398                    }
12399                    ConnectionResult::ConnectionReset => {
12400                        log::error!("Server closed a workspace diagnostics pull request");
12401                        continue 'request;
12402                    }
12403                    ConnectionResult::Result(Err(e)) => {
12404                        log::error!("Error during workspace diagnostics pull: {e:#}");
12405                        break 'request;
12406                    }
12407                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12408                        attempts = 0;
12409                        if lsp_store
12410                            .update(cx, |lsp_store, cx| {
12411                                lsp_store.apply_workspace_diagnostic_report(
12412                                    server.server_id(),
12413                                    pulled_diagnostics,
12414                                    cx,
12415                                )
12416                            })
12417                            .is_err()
12418                        {
12419                            return;
12420                        }
12421                        break 'request;
12422                    }
12423                }
12424            }
12425        }
12426    });
12427
12428    Some(WorkspaceRefreshTask {
12429        refresh_tx,
12430        progress_tx,
12431        task: workspace_query_language_server,
12432    })
12433}
12434
12435fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12436    let CompletionSource::BufferWord {
12437        word_range,
12438        resolved,
12439    } = &mut completion.source
12440    else {
12441        return;
12442    };
12443    if *resolved {
12444        return;
12445    }
12446
12447    if completion.new_text
12448        != snapshot
12449            .text_for_range(word_range.clone())
12450            .collect::<String>()
12451    {
12452        return;
12453    }
12454
12455    let mut offset = 0;
12456    for chunk in snapshot.chunks(word_range.clone(), true) {
12457        let end_offset = offset + chunk.text.len();
12458        if let Some(highlight_id) = chunk.syntax_highlight_id {
12459            completion
12460                .label
12461                .runs
12462                .push((offset..end_offset, highlight_id));
12463        }
12464        offset = end_offset;
12465    }
12466    *resolved = true;
12467}
12468
12469impl EventEmitter<LspStoreEvent> for LspStore {}
12470
12471fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12472    hover
12473        .contents
12474        .retain(|hover_block| !hover_block.text.trim().is_empty());
12475    if hover.contents.is_empty() {
12476        None
12477    } else {
12478        Some(hover)
12479    }
12480}
12481
12482async fn populate_labels_for_completions(
12483    new_completions: Vec<CoreCompletion>,
12484    language: Option<Arc<Language>>,
12485    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12486) -> Vec<Completion> {
12487    let lsp_completions = new_completions
12488        .iter()
12489        .filter_map(|new_completion| {
12490            new_completion
12491                .source
12492                .lsp_completion(true)
12493                .map(|lsp_completion| lsp_completion.into_owned())
12494        })
12495        .collect::<Vec<_>>();
12496
12497    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12498        lsp_adapter
12499            .labels_for_completions(&lsp_completions, language)
12500            .await
12501            .log_err()
12502            .unwrap_or_default()
12503    } else {
12504        Vec::new()
12505    }
12506    .into_iter()
12507    .fuse();
12508
12509    let mut completions = Vec::new();
12510    for completion in new_completions {
12511        match completion.source.lsp_completion(true) {
12512            Some(lsp_completion) => {
12513                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12514
12515                let mut label = labels.next().flatten().unwrap_or_else(|| {
12516                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12517                });
12518                ensure_uniform_list_compatible_label(&mut label);
12519                completions.push(Completion {
12520                    label,
12521                    documentation,
12522                    replace_range: completion.replace_range,
12523                    new_text: completion.new_text,
12524                    insert_text_mode: lsp_completion.insert_text_mode,
12525                    source: completion.source,
12526                    icon_path: None,
12527                    confirm: None,
12528                });
12529            }
12530            None => {
12531                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12532                ensure_uniform_list_compatible_label(&mut label);
12533                completions.push(Completion {
12534                    label,
12535                    documentation: None,
12536                    replace_range: completion.replace_range,
12537                    new_text: completion.new_text,
12538                    source: completion.source,
12539                    insert_text_mode: None,
12540                    icon_path: None,
12541                    confirm: None,
12542                });
12543            }
12544        }
12545    }
12546    completions
12547}
12548
12549#[derive(Debug)]
12550pub enum LanguageServerToQuery {
12551    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12552    FirstCapable,
12553    /// Query a specific language server.
12554    Other(LanguageServerId),
12555}
12556
12557#[derive(Default)]
12558struct RenamePathsWatchedForServer {
12559    did_rename: Vec<RenameActionPredicate>,
12560    will_rename: Vec<RenameActionPredicate>,
12561}
12562
12563impl RenamePathsWatchedForServer {
12564    fn with_did_rename_patterns(
12565        mut self,
12566        did_rename: Option<&FileOperationRegistrationOptions>,
12567    ) -> Self {
12568        if let Some(did_rename) = did_rename {
12569            self.did_rename = did_rename
12570                .filters
12571                .iter()
12572                .filter_map(|filter| filter.try_into().log_err())
12573                .collect();
12574        }
12575        self
12576    }
12577    fn with_will_rename_patterns(
12578        mut self,
12579        will_rename: Option<&FileOperationRegistrationOptions>,
12580    ) -> Self {
12581        if let Some(will_rename) = will_rename {
12582            self.will_rename = will_rename
12583                .filters
12584                .iter()
12585                .filter_map(|filter| filter.try_into().log_err())
12586                .collect();
12587        }
12588        self
12589    }
12590
12591    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12592        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12593    }
12594    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12595        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12596    }
12597}
12598
12599impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12600    type Error = globset::Error;
12601    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12602        Ok(Self {
12603            kind: ops.pattern.matches.clone(),
12604            glob: GlobBuilder::new(&ops.pattern.glob)
12605                .case_insensitive(
12606                    ops.pattern
12607                        .options
12608                        .as_ref()
12609                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12610                )
12611                .build()?
12612                .compile_matcher(),
12613        })
12614    }
12615}
12616struct RenameActionPredicate {
12617    glob: GlobMatcher,
12618    kind: Option<FileOperationPatternKind>,
12619}
12620
12621impl RenameActionPredicate {
12622    // Returns true if language server should be notified
12623    fn eval(&self, path: &str, is_dir: bool) -> bool {
12624        self.kind.as_ref().is_none_or(|kind| {
12625            let expected_kind = if is_dir {
12626                FileOperationPatternKind::Folder
12627            } else {
12628                FileOperationPatternKind::File
12629            };
12630            kind == &expected_kind
12631        }) && self.glob.is_match(path)
12632    }
12633}
12634
12635#[derive(Default)]
12636struct LanguageServerWatchedPaths {
12637    worktree_paths: HashMap<WorktreeId, GlobSet>,
12638    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12639}
12640
12641#[derive(Default)]
12642struct LanguageServerWatchedPathsBuilder {
12643    worktree_paths: HashMap<WorktreeId, GlobSet>,
12644    abs_paths: HashMap<Arc<Path>, GlobSet>,
12645}
12646
12647impl LanguageServerWatchedPathsBuilder {
12648    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12649        self.worktree_paths.insert(worktree_id, glob_set);
12650    }
12651    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12652        self.abs_paths.insert(path, glob_set);
12653    }
12654    fn build(
12655        self,
12656        fs: Arc<dyn Fs>,
12657        language_server_id: LanguageServerId,
12658        cx: &mut Context<LspStore>,
12659    ) -> LanguageServerWatchedPaths {
12660        let project = cx.weak_entity();
12661
12662        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12663        let abs_paths = self
12664            .abs_paths
12665            .into_iter()
12666            .map(|(abs_path, globset)| {
12667                let task = cx.spawn({
12668                    let abs_path = abs_path.clone();
12669                    let fs = fs.clone();
12670
12671                    let lsp_store = project.clone();
12672                    async move |_, cx| {
12673                        maybe!(async move {
12674                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12675                            while let Some(update) = push_updates.0.next().await {
12676                                let action = lsp_store
12677                                    .update(cx, |this, _| {
12678                                        let Some(local) = this.as_local() else {
12679                                            return ControlFlow::Break(());
12680                                        };
12681                                        let Some(watcher) = local
12682                                            .language_server_watched_paths
12683                                            .get(&language_server_id)
12684                                        else {
12685                                            return ControlFlow::Break(());
12686                                        };
12687                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12688                                            "Watched abs path is not registered with a watcher",
12689                                        );
12690                                        let matching_entries = update
12691                                            .into_iter()
12692                                            .filter(|event| globs.is_match(&event.path))
12693                                            .collect::<Vec<_>>();
12694                                        this.lsp_notify_abs_paths_changed(
12695                                            language_server_id,
12696                                            matching_entries,
12697                                        );
12698                                        ControlFlow::Continue(())
12699                                    })
12700                                    .ok()?;
12701
12702                                if action.is_break() {
12703                                    break;
12704                                }
12705                            }
12706                            Some(())
12707                        })
12708                        .await;
12709                    }
12710                });
12711                (abs_path, (globset, task))
12712            })
12713            .collect();
12714        LanguageServerWatchedPaths {
12715            worktree_paths: self.worktree_paths,
12716            abs_paths,
12717        }
12718    }
12719}
12720
12721struct LspBufferSnapshot {
12722    version: i32,
12723    snapshot: TextBufferSnapshot,
12724}
12725
12726/// A prompt requested by LSP server.
12727#[derive(Clone, Debug)]
12728pub struct LanguageServerPromptRequest {
12729    pub level: PromptLevel,
12730    pub message: String,
12731    pub actions: Vec<MessageActionItem>,
12732    pub lsp_name: String,
12733    pub(crate) response_channel: Sender<MessageActionItem>,
12734}
12735
12736impl LanguageServerPromptRequest {
12737    pub async fn respond(self, index: usize) -> Option<()> {
12738        if let Some(response) = self.actions.into_iter().nth(index) {
12739            self.response_channel.send(response).await.ok()
12740        } else {
12741            None
12742        }
12743    }
12744}
12745impl PartialEq for LanguageServerPromptRequest {
12746    fn eq(&self, other: &Self) -> bool {
12747        self.message == other.message && self.actions == other.actions
12748    }
12749}
12750
12751#[derive(Clone, Debug, PartialEq)]
12752pub enum LanguageServerLogType {
12753    Log(MessageType),
12754    Trace { verbose_info: Option<String> },
12755    Rpc { received: bool },
12756}
12757
12758impl LanguageServerLogType {
12759    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12760        match self {
12761            Self::Log(log_type) => {
12762                use proto::log_message::LogLevel;
12763                let level = match *log_type {
12764                    MessageType::ERROR => LogLevel::Error,
12765                    MessageType::WARNING => LogLevel::Warning,
12766                    MessageType::INFO => LogLevel::Info,
12767                    MessageType::LOG => LogLevel::Log,
12768                    other => {
12769                        log::warn!("Unknown lsp log message type: {other:?}");
12770                        LogLevel::Log
12771                    }
12772                };
12773                proto::language_server_log::LogType::Log(proto::LogMessage {
12774                    level: level as i32,
12775                })
12776            }
12777            Self::Trace { verbose_info } => {
12778                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12779                    verbose_info: verbose_info.to_owned(),
12780                })
12781            }
12782            Self::Rpc { received } => {
12783                let kind = if *received {
12784                    proto::rpc_message::Kind::Received
12785                } else {
12786                    proto::rpc_message::Kind::Sent
12787                };
12788                let kind = kind as i32;
12789                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12790            }
12791        }
12792    }
12793
12794    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12795        use proto::log_message::LogLevel;
12796        use proto::rpc_message;
12797        match log_type {
12798            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12799                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12800                    LogLevel::Error => MessageType::ERROR,
12801                    LogLevel::Warning => MessageType::WARNING,
12802                    LogLevel::Info => MessageType::INFO,
12803                    LogLevel::Log => MessageType::LOG,
12804                },
12805            ),
12806            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12807                verbose_info: trace_message.verbose_info,
12808            },
12809            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12810                received: match rpc_message::Kind::from_i32(message.kind)
12811                    .unwrap_or(rpc_message::Kind::Received)
12812                {
12813                    rpc_message::Kind::Received => true,
12814                    rpc_message::Kind::Sent => false,
12815                },
12816            },
12817        }
12818    }
12819}
12820
12821pub struct WorkspaceRefreshTask {
12822    refresh_tx: mpsc::Sender<()>,
12823    progress_tx: mpsc::Sender<()>,
12824    #[allow(dead_code)]
12825    task: Task<()>,
12826}
12827
12828pub enum LanguageServerState {
12829    Starting {
12830        startup: Task<Option<Arc<LanguageServer>>>,
12831        /// List of language servers that will be added to the workspace once it's initialization completes.
12832        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12833    },
12834
12835    Running {
12836        adapter: Arc<CachedLspAdapter>,
12837        server: Arc<LanguageServer>,
12838        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12839        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12840    },
12841}
12842
12843impl LanguageServerState {
12844    fn add_workspace_folder(&self, uri: Uri) {
12845        match self {
12846            LanguageServerState::Starting {
12847                pending_workspace_folders,
12848                ..
12849            } => {
12850                pending_workspace_folders.lock().insert(uri);
12851            }
12852            LanguageServerState::Running { server, .. } => {
12853                server.add_workspace_folder(uri);
12854            }
12855        }
12856    }
12857    fn _remove_workspace_folder(&self, uri: Uri) {
12858        match self {
12859            LanguageServerState::Starting {
12860                pending_workspace_folders,
12861                ..
12862            } => {
12863                pending_workspace_folders.lock().remove(&uri);
12864            }
12865            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12866        }
12867    }
12868}
12869
12870impl std::fmt::Debug for LanguageServerState {
12871    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12872        match self {
12873            LanguageServerState::Starting { .. } => {
12874                f.debug_struct("LanguageServerState::Starting").finish()
12875            }
12876            LanguageServerState::Running { .. } => {
12877                f.debug_struct("LanguageServerState::Running").finish()
12878            }
12879        }
12880    }
12881}
12882
12883#[derive(Clone, Debug, Serialize)]
12884pub struct LanguageServerProgress {
12885    pub is_disk_based_diagnostics_progress: bool,
12886    pub is_cancellable: bool,
12887    pub title: Option<String>,
12888    pub message: Option<String>,
12889    pub percentage: Option<usize>,
12890    #[serde(skip_serializing)]
12891    pub last_update_at: Instant,
12892}
12893
12894#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12895pub struct DiagnosticSummary {
12896    pub error_count: usize,
12897    pub warning_count: usize,
12898}
12899
12900impl DiagnosticSummary {
12901    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12902        let mut this = Self {
12903            error_count: 0,
12904            warning_count: 0,
12905        };
12906
12907        for entry in diagnostics {
12908            if entry.diagnostic.is_primary {
12909                match entry.diagnostic.severity {
12910                    DiagnosticSeverity::ERROR => this.error_count += 1,
12911                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12912                    _ => {}
12913                }
12914            }
12915        }
12916
12917        this
12918    }
12919
12920    pub fn is_empty(&self) -> bool {
12921        self.error_count == 0 && self.warning_count == 0
12922    }
12923
12924    pub fn to_proto(
12925        self,
12926        language_server_id: LanguageServerId,
12927        path: &Path,
12928    ) -> proto::DiagnosticSummary {
12929        proto::DiagnosticSummary {
12930            path: path.to_proto(),
12931            language_server_id: language_server_id.0 as u64,
12932            error_count: self.error_count as u32,
12933            warning_count: self.warning_count as u32,
12934        }
12935    }
12936}
12937
12938#[derive(Clone, Debug)]
12939pub enum CompletionDocumentation {
12940    /// There is no documentation for this completion.
12941    Undocumented,
12942    /// A single line of documentation.
12943    SingleLine(SharedString),
12944    /// Multiple lines of plain text documentation.
12945    MultiLinePlainText(SharedString),
12946    /// Markdown documentation.
12947    MultiLineMarkdown(SharedString),
12948    /// Both single line and multiple lines of plain text documentation.
12949    SingleLineAndMultiLinePlainText {
12950        single_line: SharedString,
12951        plain_text: Option<SharedString>,
12952    },
12953}
12954
12955impl CompletionDocumentation {
12956    #[cfg(any(test, feature = "test-support"))]
12957    pub fn text(&self) -> SharedString {
12958        match self {
12959            CompletionDocumentation::Undocumented => "".into(),
12960            CompletionDocumentation::SingleLine(s) => s.clone(),
12961            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12962            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12963            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12964                single_line.clone()
12965            }
12966        }
12967    }
12968}
12969
12970impl From<lsp::Documentation> for CompletionDocumentation {
12971    fn from(docs: lsp::Documentation) -> Self {
12972        match docs {
12973            lsp::Documentation::String(text) => {
12974                if text.lines().count() <= 1 {
12975                    CompletionDocumentation::SingleLine(text.into())
12976                } else {
12977                    CompletionDocumentation::MultiLinePlainText(text.into())
12978                }
12979            }
12980
12981            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12982                lsp::MarkupKind::PlainText => {
12983                    if value.lines().count() <= 1 {
12984                        CompletionDocumentation::SingleLine(value.into())
12985                    } else {
12986                        CompletionDocumentation::MultiLinePlainText(value.into())
12987                    }
12988                }
12989
12990                lsp::MarkupKind::Markdown => {
12991                    CompletionDocumentation::MultiLineMarkdown(value.into())
12992                }
12993            },
12994        }
12995    }
12996}
12997
12998fn glob_literal_prefix(glob: &Path) -> PathBuf {
12999    glob.components()
13000        .take_while(|component| match component {
13001            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13002            _ => true,
13003        })
13004        .collect()
13005}
13006
13007pub struct SshLspAdapter {
13008    name: LanguageServerName,
13009    binary: LanguageServerBinary,
13010    initialization_options: Option<String>,
13011    code_action_kinds: Option<Vec<CodeActionKind>>,
13012}
13013
13014impl SshLspAdapter {
13015    pub fn new(
13016        name: LanguageServerName,
13017        binary: LanguageServerBinary,
13018        initialization_options: Option<String>,
13019        code_action_kinds: Option<String>,
13020    ) -> Self {
13021        Self {
13022            name,
13023            binary,
13024            initialization_options,
13025            code_action_kinds: code_action_kinds
13026                .as_ref()
13027                .and_then(|c| serde_json::from_str(c).ok()),
13028        }
13029    }
13030}
13031
13032#[async_trait(?Send)]
13033impl LspAdapter for SshLspAdapter {
13034    fn name(&self) -> LanguageServerName {
13035        self.name.clone()
13036    }
13037
13038    async fn initialization_options(
13039        self: Arc<Self>,
13040        _: &dyn Fs,
13041        _: &Arc<dyn LspAdapterDelegate>,
13042    ) -> Result<Option<serde_json::Value>> {
13043        let Some(options) = &self.initialization_options else {
13044            return Ok(None);
13045        };
13046        let result = serde_json::from_str(options)?;
13047        Ok(result)
13048    }
13049
13050    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13051        self.code_action_kinds.clone()
13052    }
13053
13054    async fn check_if_user_installed(
13055        &self,
13056        _: &dyn LspAdapterDelegate,
13057        _: Option<Toolchain>,
13058        _: &AsyncApp,
13059    ) -> Option<LanguageServerBinary> {
13060        Some(self.binary.clone())
13061    }
13062
13063    async fn cached_server_binary(
13064        &self,
13065        _: PathBuf,
13066        _: &dyn LspAdapterDelegate,
13067    ) -> Option<LanguageServerBinary> {
13068        None
13069    }
13070
13071    async fn fetch_latest_server_version(
13072        &self,
13073        _: &dyn LspAdapterDelegate,
13074    ) -> Result<Box<dyn 'static + Send + Any>> {
13075        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13076    }
13077
13078    async fn fetch_server_binary(
13079        &self,
13080        _: Box<dyn 'static + Send + Any>,
13081        _: PathBuf,
13082        _: &dyn LspAdapterDelegate,
13083    ) -> Result<LanguageServerBinary> {
13084        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13085    }
13086}
13087
13088pub fn language_server_settings<'a>(
13089    delegate: &'a dyn LspAdapterDelegate,
13090    language: &LanguageServerName,
13091    cx: &'a App,
13092) -> Option<&'a LspSettings> {
13093    language_server_settings_for(
13094        SettingsLocation {
13095            worktree_id: delegate.worktree_id(),
13096            path: delegate.worktree_root_path(),
13097        },
13098        language,
13099        cx,
13100    )
13101}
13102
13103pub(crate) fn language_server_settings_for<'a>(
13104    location: SettingsLocation<'a>,
13105    language: &LanguageServerName,
13106    cx: &'a App,
13107) -> Option<&'a LspSettings> {
13108    ProjectSettings::get(Some(location), cx).lsp.get(language)
13109}
13110
13111pub struct LocalLspAdapterDelegate {
13112    lsp_store: WeakEntity<LspStore>,
13113    worktree: worktree::Snapshot,
13114    fs: Arc<dyn Fs>,
13115    http_client: Arc<dyn HttpClient>,
13116    language_registry: Arc<LanguageRegistry>,
13117    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13118}
13119
13120impl LocalLspAdapterDelegate {
13121    pub fn new(
13122        language_registry: Arc<LanguageRegistry>,
13123        environment: &Entity<ProjectEnvironment>,
13124        lsp_store: WeakEntity<LspStore>,
13125        worktree: &Entity<Worktree>,
13126        http_client: Arc<dyn HttpClient>,
13127        fs: Arc<dyn Fs>,
13128        cx: &mut App,
13129    ) -> Arc<Self> {
13130        let load_shell_env_task = environment.update(cx, |env, cx| {
13131            env.get_worktree_environment(worktree.clone(), cx)
13132        });
13133
13134        Arc::new(Self {
13135            lsp_store,
13136            worktree: worktree.read(cx).snapshot(),
13137            fs,
13138            http_client,
13139            language_registry,
13140            load_shell_env_task,
13141        })
13142    }
13143
13144    fn from_local_lsp(
13145        local: &LocalLspStore,
13146        worktree: &Entity<Worktree>,
13147        cx: &mut App,
13148    ) -> Arc<Self> {
13149        Self::new(
13150            local.languages.clone(),
13151            &local.environment,
13152            local.weak.clone(),
13153            worktree,
13154            local.http_client.clone(),
13155            local.fs.clone(),
13156            cx,
13157        )
13158    }
13159}
13160
13161#[async_trait]
13162impl LspAdapterDelegate for LocalLspAdapterDelegate {
13163    fn show_notification(&self, message: &str, cx: &mut App) {
13164        self.lsp_store
13165            .update(cx, |_, cx| {
13166                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13167            })
13168            .ok();
13169    }
13170
13171    fn http_client(&self) -> Arc<dyn HttpClient> {
13172        self.http_client.clone()
13173    }
13174
13175    fn worktree_id(&self) -> WorktreeId {
13176        self.worktree.id()
13177    }
13178
13179    fn worktree_root_path(&self) -> &Path {
13180        self.worktree.abs_path().as_ref()
13181    }
13182
13183    async fn shell_env(&self) -> HashMap<String, String> {
13184        let task = self.load_shell_env_task.clone();
13185        task.await.unwrap_or_default()
13186    }
13187
13188    async fn npm_package_installed_version(
13189        &self,
13190        package_name: &str,
13191    ) -> Result<Option<(PathBuf, String)>> {
13192        let local_package_directory = self.worktree_root_path();
13193        let node_modules_directory = local_package_directory.join("node_modules");
13194
13195        if let Some(version) =
13196            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13197        {
13198            return Ok(Some((node_modules_directory, version)));
13199        }
13200        let Some(npm) = self.which("npm".as_ref()).await else {
13201            log::warn!(
13202                "Failed to find npm executable for {:?}",
13203                local_package_directory
13204            );
13205            return Ok(None);
13206        };
13207
13208        let env = self.shell_env().await;
13209        let output = util::command::new_smol_command(&npm)
13210            .args(["root", "-g"])
13211            .envs(env)
13212            .current_dir(local_package_directory)
13213            .output()
13214            .await?;
13215        let global_node_modules =
13216            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13217
13218        if let Some(version) =
13219            read_package_installed_version(global_node_modules.clone(), package_name).await?
13220        {
13221            return Ok(Some((global_node_modules, version)));
13222        }
13223        return Ok(None);
13224    }
13225
13226    #[cfg(not(target_os = "windows"))]
13227    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13228        let worktree_abs_path = self.worktree.abs_path();
13229        let shell_path = self.shell_env().await.get("PATH").cloned();
13230        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13231    }
13232
13233    #[cfg(target_os = "windows")]
13234    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13235        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
13236        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
13237        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
13238        which::which(command).ok()
13239    }
13240
13241    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13242        let working_dir = self.worktree_root_path();
13243        let output = util::command::new_smol_command(&command.path)
13244            .args(command.arguments)
13245            .envs(command.env.clone().unwrap_or_default())
13246            .current_dir(working_dir)
13247            .output()
13248            .await?;
13249
13250        anyhow::ensure!(
13251            output.status.success(),
13252            "{}, stdout: {:?}, stderr: {:?}",
13253            output.status,
13254            String::from_utf8_lossy(&output.stdout),
13255            String::from_utf8_lossy(&output.stderr)
13256        );
13257        Ok(())
13258    }
13259
13260    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13261        self.language_registry
13262            .update_lsp_binary_status(server_name, status);
13263    }
13264
13265    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13266        self.language_registry
13267            .all_lsp_adapters()
13268            .into_iter()
13269            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13270            .collect()
13271    }
13272
13273    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13274        let dir = self.language_registry.language_server_download_dir(name)?;
13275
13276        if !dir.exists() {
13277            smol::fs::create_dir_all(&dir)
13278                .await
13279                .context("failed to create container directory")
13280                .log_err()?;
13281        }
13282
13283        Some(dir)
13284    }
13285
13286    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
13287        let entry = self
13288            .worktree
13289            .entry_for_path(&path)
13290            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13291        let abs_path = self
13292            .worktree
13293            .absolutize(&entry.path)
13294            .with_context(|| format!("cannot absolutize path {path:?}"))?;
13295
13296        self.fs.load(&abs_path).await
13297    }
13298}
13299
13300async fn populate_labels_for_symbols(
13301    symbols: Vec<CoreSymbol>,
13302    language_registry: &Arc<LanguageRegistry>,
13303    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13304    output: &mut Vec<Symbol>,
13305) {
13306    #[allow(clippy::mutable_key_type)]
13307    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13308
13309    let mut unknown_paths = BTreeSet::new();
13310    for symbol in symbols {
13311        let language = language_registry
13312            .language_for_file_path(&symbol.path.path)
13313            .await
13314            .ok()
13315            .or_else(|| {
13316                unknown_paths.insert(symbol.path.path.clone());
13317                None
13318            });
13319        symbols_by_language
13320            .entry(language)
13321            .or_default()
13322            .push(symbol);
13323    }
13324
13325    for unknown_path in unknown_paths {
13326        log::info!(
13327            "no language found for symbol path {}",
13328            unknown_path.display()
13329        );
13330    }
13331
13332    let mut label_params = Vec::new();
13333    for (language, mut symbols) in symbols_by_language {
13334        label_params.clear();
13335        label_params.extend(
13336            symbols
13337                .iter_mut()
13338                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13339        );
13340
13341        let mut labels = Vec::new();
13342        if let Some(language) = language {
13343            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13344                language_registry
13345                    .lsp_adapters(&language.name())
13346                    .first()
13347                    .cloned()
13348            });
13349            if let Some(lsp_adapter) = lsp_adapter {
13350                labels = lsp_adapter
13351                    .labels_for_symbols(&label_params, &language)
13352                    .await
13353                    .log_err()
13354                    .unwrap_or_default();
13355            }
13356        }
13357
13358        for ((symbol, (name, _)), label) in symbols
13359            .into_iter()
13360            .zip(label_params.drain(..))
13361            .zip(labels.into_iter().chain(iter::repeat(None)))
13362        {
13363            output.push(Symbol {
13364                language_server_name: symbol.language_server_name,
13365                source_worktree_id: symbol.source_worktree_id,
13366                source_language_server_id: symbol.source_language_server_id,
13367                path: symbol.path,
13368                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13369                name,
13370                kind: symbol.kind,
13371                range: symbol.range,
13372                signature: symbol.signature,
13373            });
13374        }
13375    }
13376}
13377
13378fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13379    match server.capabilities().text_document_sync.as_ref()? {
13380        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13381            // Server wants didSave but didn't specify includeText.
13382            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13383            // Server doesn't want didSave at all.
13384            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13385            // Server provided SaveOptions.
13386            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13387                Some(save_options.include_text.unwrap_or(false))
13388            }
13389        },
13390        // We do not have any save info. Kind affects didChange only.
13391        lsp::TextDocumentSyncCapability::Kind(_) => None,
13392    }
13393}
13394
13395/// Completion items are displayed in a `UniformList`.
13396/// Usually, those items are single-line strings, but in LSP responses,
13397/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13398/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13399/// 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,
13400/// breaking the completions menu presentation.
13401///
13402/// 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.
13403fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13404    let mut new_text = String::with_capacity(label.text.len());
13405    let mut offset_map = vec![0; label.text.len() + 1];
13406    let mut last_char_was_space = false;
13407    let mut new_idx = 0;
13408    let chars = label.text.char_indices().fuse();
13409    let mut newlines_removed = false;
13410
13411    for (idx, c) in chars {
13412        offset_map[idx] = new_idx;
13413
13414        match c {
13415            '\n' if last_char_was_space => {
13416                newlines_removed = true;
13417            }
13418            '\t' | ' ' if last_char_was_space => {}
13419            '\n' if !last_char_was_space => {
13420                new_text.push(' ');
13421                new_idx += 1;
13422                last_char_was_space = true;
13423                newlines_removed = true;
13424            }
13425            ' ' | '\t' => {
13426                new_text.push(' ');
13427                new_idx += 1;
13428                last_char_was_space = true;
13429            }
13430            _ => {
13431                new_text.push(c);
13432                new_idx += c.len_utf8();
13433                last_char_was_space = false;
13434            }
13435        }
13436    }
13437    offset_map[label.text.len()] = new_idx;
13438
13439    // Only modify the label if newlines were removed.
13440    if !newlines_removed {
13441        return;
13442    }
13443
13444    let last_index = new_idx;
13445    let mut run_ranges_errors = Vec::new();
13446    label.runs.retain_mut(|(range, _)| {
13447        match offset_map.get(range.start) {
13448            Some(&start) => range.start = start,
13449            None => {
13450                run_ranges_errors.push(range.clone());
13451                return false;
13452            }
13453        }
13454
13455        match offset_map.get(range.end) {
13456            Some(&end) => range.end = end,
13457            None => {
13458                run_ranges_errors.push(range.clone());
13459                range.end = last_index;
13460            }
13461        }
13462        true
13463    });
13464    if !run_ranges_errors.is_empty() {
13465        log::error!(
13466            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13467            label.text
13468        );
13469    }
13470
13471    let mut wrong_filter_range = None;
13472    if label.filter_range == (0..label.text.len()) {
13473        label.filter_range = 0..new_text.len();
13474    } else {
13475        let mut original_filter_range = Some(label.filter_range.clone());
13476        match offset_map.get(label.filter_range.start) {
13477            Some(&start) => label.filter_range.start = start,
13478            None => {
13479                wrong_filter_range = original_filter_range.take();
13480                label.filter_range.start = last_index;
13481            }
13482        }
13483
13484        match offset_map.get(label.filter_range.end) {
13485            Some(&end) => label.filter_range.end = end,
13486            None => {
13487                wrong_filter_range = original_filter_range.take();
13488                label.filter_range.end = last_index;
13489            }
13490        }
13491    }
13492    if let Some(wrong_filter_range) = wrong_filter_range {
13493        log::error!(
13494            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13495            label.text
13496        );
13497    }
13498
13499    label.text = new_text;
13500}
13501
13502#[cfg(test)]
13503mod tests {
13504    use language::HighlightId;
13505
13506    use super::*;
13507
13508    #[test]
13509    fn test_glob_literal_prefix() {
13510        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13511        assert_eq!(
13512            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13513            Path::new("node_modules")
13514        );
13515        assert_eq!(
13516            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13517            Path::new("foo")
13518        );
13519        assert_eq!(
13520            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13521            Path::new("foo/bar/baz.js")
13522        );
13523
13524        #[cfg(target_os = "windows")]
13525        {
13526            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13527            assert_eq!(
13528                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13529                Path::new("node_modules")
13530            );
13531            assert_eq!(
13532                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13533                Path::new("foo")
13534            );
13535            assert_eq!(
13536                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13537                Path::new("foo/bar/baz.js")
13538            );
13539        }
13540    }
13541
13542    #[test]
13543    fn test_multi_len_chars_normalization() {
13544        let mut label = CodeLabel {
13545            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13546            runs: vec![(0..6, HighlightId(1))],
13547            filter_range: 0..6,
13548        };
13549        ensure_uniform_list_compatible_label(&mut label);
13550        assert_eq!(
13551            label,
13552            CodeLabel {
13553                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13554                runs: vec![(0..6, HighlightId(1))],
13555                filter_range: 0..6,
13556            }
13557        );
13558    }
13559}