lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17
   18use crate::{
   19    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   20    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction,
   21    LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   22    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   23    buffer_store::{BufferStore, BufferStoreEvent},
   24    environment::ProjectEnvironment,
   25    lsp_command::{self, *},
   26    lsp_store::{
   27        self,
   28        log_store::{GlobalLogStore, LanguageServerKind},
   29    },
   30    manifest_tree::{
   31        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   32        ManifestTree,
   33    },
   34    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   35    project_settings::{LspSettings, ProjectSettings},
   36    relativize_path, resolve_path,
   37    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   38    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   39    yarn::YarnPathStore,
   40};
   41use anyhow::{Context as _, Result, anyhow};
   42use async_trait::async_trait;
   43use client::{TypedEnvelope, proto};
   44use clock::Global;
   45use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   46use futures::{
   47    AsyncWriteExt, Future, FutureExt, StreamExt,
   48    future::{Either, Shared, join_all, pending, select},
   49    select, select_biased,
   50    stream::FuturesUnordered,
   51};
   52use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   53use gpui::{
   54    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   55    WeakEntity,
   56};
   57use http_client::HttpClient;
   58use itertools::Itertools as _;
   59use language::{
   60    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   61    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   62    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, ManifestDelegate, ManifestName,
   63    Patch, PointUtf16, TextBufferSnapshot, ToOffset, 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                    display_options: CompletionDisplayOptions::default(),
 5832                    is_incomplete: completion_response.is_incomplete,
 5833                }])
 5834            })
 5835        } else if let Some(local) = self.as_local() {
 5836            let snapshot = buffer.read(cx).snapshot();
 5837            let offset = position.to_offset(&snapshot);
 5838            let scope = snapshot.language_scope_at(offset);
 5839            let language = snapshot.language().cloned();
 5840            let completion_settings = language_settings(
 5841                language.as_ref().map(|language| language.name()),
 5842                buffer.read(cx).file(),
 5843                cx,
 5844            )
 5845            .completions;
 5846            if !completion_settings.lsp {
 5847                return Task::ready(Ok(Vec::new()));
 5848            }
 5849
 5850            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5851                local
 5852                    .language_servers_for_buffer(buffer, cx)
 5853                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5854                    .filter(|(adapter, _)| {
 5855                        scope
 5856                            .as_ref()
 5857                            .map(|scope| scope.language_allowed(&adapter.name))
 5858                            .unwrap_or(true)
 5859                    })
 5860                    .map(|(_, server)| server.server_id())
 5861                    .collect()
 5862            });
 5863
 5864            let buffer = buffer.clone();
 5865            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5866            let lsp_timeout = if lsp_timeout > 0 {
 5867                Some(Duration::from_millis(lsp_timeout))
 5868            } else {
 5869                None
 5870            };
 5871            cx.spawn(async move |this,  cx| {
 5872                let mut tasks = Vec::with_capacity(server_ids.len());
 5873                this.update(cx, |lsp_store, cx| {
 5874                    for server_id in server_ids {
 5875                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5876                        let lsp_timeout = lsp_timeout
 5877                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5878                        let mut timeout = cx.background_spawn(async move {
 5879                            match lsp_timeout {
 5880                                Some(lsp_timeout) => {
 5881                                    lsp_timeout.await;
 5882                                    true
 5883                                },
 5884                                None => false,
 5885                            }
 5886                        }).fuse();
 5887                        let mut lsp_request = lsp_store.request_lsp(
 5888                            buffer.clone(),
 5889                            LanguageServerToQuery::Other(server_id),
 5890                            GetCompletions {
 5891                                position,
 5892                                context: context.clone(),
 5893                            },
 5894                            cx,
 5895                        ).fuse();
 5896                        let new_task = cx.background_spawn(async move {
 5897                            select_biased! {
 5898                                response = lsp_request => anyhow::Ok(Some(response?)),
 5899                                timeout_happened = timeout => {
 5900                                    if timeout_happened {
 5901                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5902                                        Ok(None)
 5903                                    } else {
 5904                                        let completions = lsp_request.await?;
 5905                                        Ok(Some(completions))
 5906                                    }
 5907                                },
 5908                            }
 5909                        });
 5910                        tasks.push((lsp_adapter, new_task));
 5911                    }
 5912                })?;
 5913
 5914                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5915                    let completion_response = task.await.ok()??;
 5916                    let completions = populate_labels_for_completions(
 5917                            completion_response.completions,
 5918                            language.clone(),
 5919                            lsp_adapter,
 5920                        )
 5921                        .await;
 5922                    Some(CompletionResponse {
 5923                        completions,
 5924                        display_options: CompletionDisplayOptions::default(),
 5925                        is_incomplete: completion_response.is_incomplete,
 5926                    })
 5927                });
 5928
 5929                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5930
 5931                Ok(responses.into_iter().flatten().collect())
 5932            })
 5933        } else {
 5934            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5935        }
 5936    }
 5937
 5938    pub fn resolve_completions(
 5939        &self,
 5940        buffer: Entity<Buffer>,
 5941        completion_indices: Vec<usize>,
 5942        completions: Rc<RefCell<Box<[Completion]>>>,
 5943        cx: &mut Context<Self>,
 5944    ) -> Task<Result<bool>> {
 5945        let client = self.upstream_client();
 5946        let buffer_id = buffer.read(cx).remote_id();
 5947        let buffer_snapshot = buffer.read(cx).snapshot();
 5948
 5949        if !self.check_if_capable_for_proto_request(
 5950            &buffer,
 5951            GetCompletions::can_resolve_completions,
 5952            cx,
 5953        ) {
 5954            return Task::ready(Ok(false));
 5955        }
 5956        cx.spawn(async move |lsp_store, cx| {
 5957            let mut did_resolve = false;
 5958            if let Some((client, project_id)) = client {
 5959                for completion_index in completion_indices {
 5960                    let server_id = {
 5961                        let completion = &completions.borrow()[completion_index];
 5962                        completion.source.server_id()
 5963                    };
 5964                    if let Some(server_id) = server_id {
 5965                        if Self::resolve_completion_remote(
 5966                            project_id,
 5967                            server_id,
 5968                            buffer_id,
 5969                            completions.clone(),
 5970                            completion_index,
 5971                            client.clone(),
 5972                        )
 5973                        .await
 5974                        .log_err()
 5975                        .is_some()
 5976                        {
 5977                            did_resolve = true;
 5978                        }
 5979                    } else {
 5980                        resolve_word_completion(
 5981                            &buffer_snapshot,
 5982                            &mut completions.borrow_mut()[completion_index],
 5983                        );
 5984                    }
 5985                }
 5986            } else {
 5987                for completion_index in completion_indices {
 5988                    let server_id = {
 5989                        let completion = &completions.borrow()[completion_index];
 5990                        completion.source.server_id()
 5991                    };
 5992                    if let Some(server_id) = server_id {
 5993                        let server_and_adapter = lsp_store
 5994                            .read_with(cx, |lsp_store, _| {
 5995                                let server = lsp_store.language_server_for_id(server_id)?;
 5996                                let adapter =
 5997                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5998                                Some((server, adapter))
 5999                            })
 6000                            .ok()
 6001                            .flatten();
 6002                        let Some((server, adapter)) = server_and_adapter else {
 6003                            continue;
 6004                        };
 6005
 6006                        let resolved = Self::resolve_completion_local(
 6007                            server,
 6008                            completions.clone(),
 6009                            completion_index,
 6010                        )
 6011                        .await
 6012                        .log_err()
 6013                        .is_some();
 6014                        if resolved {
 6015                            Self::regenerate_completion_labels(
 6016                                adapter,
 6017                                &buffer_snapshot,
 6018                                completions.clone(),
 6019                                completion_index,
 6020                            )
 6021                            .await
 6022                            .log_err();
 6023                            did_resolve = true;
 6024                        }
 6025                    } else {
 6026                        resolve_word_completion(
 6027                            &buffer_snapshot,
 6028                            &mut completions.borrow_mut()[completion_index],
 6029                        );
 6030                    }
 6031                }
 6032            }
 6033
 6034            Ok(did_resolve)
 6035        })
 6036    }
 6037
 6038    async fn resolve_completion_local(
 6039        server: Arc<lsp::LanguageServer>,
 6040        completions: Rc<RefCell<Box<[Completion]>>>,
 6041        completion_index: usize,
 6042    ) -> Result<()> {
 6043        let server_id = server.server_id();
 6044        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6045            return Ok(());
 6046        }
 6047
 6048        let request = {
 6049            let completion = &completions.borrow()[completion_index];
 6050            match &completion.source {
 6051                CompletionSource::Lsp {
 6052                    lsp_completion,
 6053                    resolved,
 6054                    server_id: completion_server_id,
 6055                    ..
 6056                } => {
 6057                    if *resolved {
 6058                        return Ok(());
 6059                    }
 6060                    anyhow::ensure!(
 6061                        server_id == *completion_server_id,
 6062                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6063                    );
 6064                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6065                }
 6066                CompletionSource::BufferWord { .. }
 6067                | CompletionSource::Dap { .. }
 6068                | CompletionSource::Custom => {
 6069                    return Ok(());
 6070                }
 6071            }
 6072        };
 6073        let resolved_completion = request
 6074            .await
 6075            .into_response()
 6076            .context("resolve completion")?;
 6077
 6078        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6079        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6080
 6081        let mut completions = completions.borrow_mut();
 6082        let completion = &mut completions[completion_index];
 6083        if let CompletionSource::Lsp {
 6084            lsp_completion,
 6085            resolved,
 6086            server_id: completion_server_id,
 6087            ..
 6088        } = &mut completion.source
 6089        {
 6090            if *resolved {
 6091                return Ok(());
 6092            }
 6093            anyhow::ensure!(
 6094                server_id == *completion_server_id,
 6095                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6096            );
 6097            *lsp_completion = Box::new(resolved_completion);
 6098            *resolved = true;
 6099        }
 6100        Ok(())
 6101    }
 6102
 6103    async fn regenerate_completion_labels(
 6104        adapter: Arc<CachedLspAdapter>,
 6105        snapshot: &BufferSnapshot,
 6106        completions: Rc<RefCell<Box<[Completion]>>>,
 6107        completion_index: usize,
 6108    ) -> Result<()> {
 6109        let completion_item = completions.borrow()[completion_index]
 6110            .source
 6111            .lsp_completion(true)
 6112            .map(Cow::into_owned);
 6113        if let Some(lsp_documentation) = completion_item
 6114            .as_ref()
 6115            .and_then(|completion_item| completion_item.documentation.clone())
 6116        {
 6117            let mut completions = completions.borrow_mut();
 6118            let completion = &mut completions[completion_index];
 6119            completion.documentation = Some(lsp_documentation.into());
 6120        } else {
 6121            let mut completions = completions.borrow_mut();
 6122            let completion = &mut completions[completion_index];
 6123            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6124        }
 6125
 6126        let mut new_label = match completion_item {
 6127            Some(completion_item) => {
 6128                // 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
 6129                // So we have to update the label here anyway...
 6130                let language = snapshot.language();
 6131                match language {
 6132                    Some(language) => {
 6133                        adapter
 6134                            .labels_for_completions(
 6135                                std::slice::from_ref(&completion_item),
 6136                                language,
 6137                            )
 6138                            .await?
 6139                    }
 6140                    None => Vec::new(),
 6141                }
 6142                .pop()
 6143                .flatten()
 6144                .unwrap_or_else(|| {
 6145                    CodeLabel::fallback_for_completion(
 6146                        &completion_item,
 6147                        language.map(|language| language.as_ref()),
 6148                    )
 6149                })
 6150            }
 6151            None => CodeLabel::plain(
 6152                completions.borrow()[completion_index].new_text.clone(),
 6153                None,
 6154            ),
 6155        };
 6156        ensure_uniform_list_compatible_label(&mut new_label);
 6157
 6158        let mut completions = completions.borrow_mut();
 6159        let completion = &mut completions[completion_index];
 6160        if completion.label.filter_text() == new_label.filter_text() {
 6161            completion.label = new_label;
 6162        } else {
 6163            log::error!(
 6164                "Resolved completion changed display label from {} to {}. \
 6165                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6166                completion.label.text(),
 6167                new_label.text(),
 6168                completion.label.filter_text(),
 6169                new_label.filter_text()
 6170            );
 6171        }
 6172
 6173        Ok(())
 6174    }
 6175
 6176    async fn resolve_completion_remote(
 6177        project_id: u64,
 6178        server_id: LanguageServerId,
 6179        buffer_id: BufferId,
 6180        completions: Rc<RefCell<Box<[Completion]>>>,
 6181        completion_index: usize,
 6182        client: AnyProtoClient,
 6183    ) -> Result<()> {
 6184        let lsp_completion = {
 6185            let completion = &completions.borrow()[completion_index];
 6186            match &completion.source {
 6187                CompletionSource::Lsp {
 6188                    lsp_completion,
 6189                    resolved,
 6190                    server_id: completion_server_id,
 6191                    ..
 6192                } => {
 6193                    anyhow::ensure!(
 6194                        server_id == *completion_server_id,
 6195                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6196                    );
 6197                    if *resolved {
 6198                        return Ok(());
 6199                    }
 6200                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6201                }
 6202                CompletionSource::Custom
 6203                | CompletionSource::Dap { .. }
 6204                | CompletionSource::BufferWord { .. } => {
 6205                    return Ok(());
 6206                }
 6207            }
 6208        };
 6209        let request = proto::ResolveCompletionDocumentation {
 6210            project_id,
 6211            language_server_id: server_id.0 as u64,
 6212            lsp_completion,
 6213            buffer_id: buffer_id.into(),
 6214        };
 6215
 6216        let response = client
 6217            .request(request)
 6218            .await
 6219            .context("completion documentation resolve proto request")?;
 6220        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6221
 6222        let documentation = if response.documentation.is_empty() {
 6223            CompletionDocumentation::Undocumented
 6224        } else if response.documentation_is_markdown {
 6225            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6226        } else if response.documentation.lines().count() <= 1 {
 6227            CompletionDocumentation::SingleLine(response.documentation.into())
 6228        } else {
 6229            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6230        };
 6231
 6232        let mut completions = completions.borrow_mut();
 6233        let completion = &mut completions[completion_index];
 6234        completion.documentation = Some(documentation);
 6235        if let CompletionSource::Lsp {
 6236            insert_range,
 6237            lsp_completion,
 6238            resolved,
 6239            server_id: completion_server_id,
 6240            lsp_defaults: _,
 6241        } = &mut completion.source
 6242        {
 6243            let completion_insert_range = response
 6244                .old_insert_start
 6245                .and_then(deserialize_anchor)
 6246                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6247            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6248
 6249            if *resolved {
 6250                return Ok(());
 6251            }
 6252            anyhow::ensure!(
 6253                server_id == *completion_server_id,
 6254                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6255            );
 6256            *lsp_completion = Box::new(resolved_lsp_completion);
 6257            *resolved = true;
 6258        }
 6259
 6260        let replace_range = response
 6261            .old_replace_start
 6262            .and_then(deserialize_anchor)
 6263            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6264        if let Some((old_replace_start, old_replace_end)) = replace_range
 6265            && !response.new_text.is_empty()
 6266        {
 6267            completion.new_text = response.new_text;
 6268            completion.replace_range = old_replace_start..old_replace_end;
 6269        }
 6270
 6271        Ok(())
 6272    }
 6273
 6274    pub fn apply_additional_edits_for_completion(
 6275        &self,
 6276        buffer_handle: Entity<Buffer>,
 6277        completions: Rc<RefCell<Box<[Completion]>>>,
 6278        completion_index: usize,
 6279        push_to_history: bool,
 6280        cx: &mut Context<Self>,
 6281    ) -> Task<Result<Option<Transaction>>> {
 6282        if let Some((client, project_id)) = self.upstream_client() {
 6283            let buffer = buffer_handle.read(cx);
 6284            let buffer_id = buffer.remote_id();
 6285            cx.spawn(async move |_, cx| {
 6286                let request = {
 6287                    let completion = completions.borrow()[completion_index].clone();
 6288                    proto::ApplyCompletionAdditionalEdits {
 6289                        project_id,
 6290                        buffer_id: buffer_id.into(),
 6291                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6292                            replace_range: completion.replace_range,
 6293                            new_text: completion.new_text,
 6294                            source: completion.source,
 6295                        })),
 6296                    }
 6297                };
 6298
 6299                if let Some(transaction) = client.request(request).await?.transaction {
 6300                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6301                    buffer_handle
 6302                        .update(cx, |buffer, _| {
 6303                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6304                        })?
 6305                        .await?;
 6306                    if push_to_history {
 6307                        buffer_handle.update(cx, |buffer, _| {
 6308                            buffer.push_transaction(transaction.clone(), Instant::now());
 6309                            buffer.finalize_last_transaction();
 6310                        })?;
 6311                    }
 6312                    Ok(Some(transaction))
 6313                } else {
 6314                    Ok(None)
 6315                }
 6316            })
 6317        } else {
 6318            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6319                let completion = &completions.borrow()[completion_index];
 6320                let server_id = completion.source.server_id()?;
 6321                Some(
 6322                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6323                        .1
 6324                        .clone(),
 6325                )
 6326            }) else {
 6327                return Task::ready(Ok(None));
 6328            };
 6329
 6330            cx.spawn(async move |this, cx| {
 6331                Self::resolve_completion_local(
 6332                    server.clone(),
 6333                    completions.clone(),
 6334                    completion_index,
 6335                )
 6336                .await
 6337                .context("resolving completion")?;
 6338                let completion = completions.borrow()[completion_index].clone();
 6339                let additional_text_edits = completion
 6340                    .source
 6341                    .lsp_completion(true)
 6342                    .as_ref()
 6343                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6344                if let Some(edits) = additional_text_edits {
 6345                    let edits = this
 6346                        .update(cx, |this, cx| {
 6347                            this.as_local_mut().unwrap().edits_from_lsp(
 6348                                &buffer_handle,
 6349                                edits,
 6350                                server.server_id(),
 6351                                None,
 6352                                cx,
 6353                            )
 6354                        })?
 6355                        .await?;
 6356
 6357                    buffer_handle.update(cx, |buffer, cx| {
 6358                        buffer.finalize_last_transaction();
 6359                        buffer.start_transaction();
 6360
 6361                        for (range, text) in edits {
 6362                            let primary = &completion.replace_range;
 6363                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6364                                && primary.end.cmp(&range.start, buffer).is_ge();
 6365                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6366                                && range.end.cmp(&primary.end, buffer).is_ge();
 6367
 6368                            //Skip additional edits which overlap with the primary completion edit
 6369                            //https://github.com/zed-industries/zed/pull/1871
 6370                            if !start_within && !end_within {
 6371                                buffer.edit([(range, text)], None, cx);
 6372                            }
 6373                        }
 6374
 6375                        let transaction = if buffer.end_transaction(cx).is_some() {
 6376                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6377                            if !push_to_history {
 6378                                buffer.forget_transaction(transaction.id);
 6379                            }
 6380                            Some(transaction)
 6381                        } else {
 6382                            None
 6383                        };
 6384                        Ok(transaction)
 6385                    })?
 6386                } else {
 6387                    Ok(None)
 6388                }
 6389            })
 6390        }
 6391    }
 6392
 6393    pub fn pull_diagnostics(
 6394        &mut self,
 6395        buffer: Entity<Buffer>,
 6396        cx: &mut Context<Self>,
 6397    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6398        let buffer_id = buffer.read(cx).remote_id();
 6399
 6400        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6401            let request = GetDocumentDiagnostics {
 6402                previous_result_id: None,
 6403            };
 6404            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6405                return Task::ready(Ok(None));
 6406            }
 6407            let request_task = client.request_lsp(
 6408                upstream_project_id,
 6409                LSP_REQUEST_TIMEOUT,
 6410                cx.background_executor().clone(),
 6411                request.to_proto(upstream_project_id, buffer.read(cx)),
 6412            );
 6413            cx.background_spawn(async move {
 6414                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6415                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6416                // Do not attempt to further process the dummy responses here.
 6417                let _response = request_task.await?;
 6418                Ok(None)
 6419            })
 6420        } else {
 6421            let server_ids = buffer.update(cx, |buffer, cx| {
 6422                self.language_servers_for_local_buffer(buffer, cx)
 6423                    .map(|(_, server)| server.server_id())
 6424                    .collect::<Vec<_>>()
 6425            });
 6426            let pull_diagnostics = server_ids
 6427                .into_iter()
 6428                .map(|server_id| {
 6429                    let result_id = self.result_id(server_id, buffer_id, cx);
 6430                    self.request_lsp(
 6431                        buffer.clone(),
 6432                        LanguageServerToQuery::Other(server_id),
 6433                        GetDocumentDiagnostics {
 6434                            previous_result_id: result_id,
 6435                        },
 6436                        cx,
 6437                    )
 6438                })
 6439                .collect::<Vec<_>>();
 6440
 6441            cx.background_spawn(async move {
 6442                let mut responses = Vec::new();
 6443                for diagnostics in join_all(pull_diagnostics).await {
 6444                    responses.extend(diagnostics?);
 6445                }
 6446                Ok(Some(responses))
 6447            })
 6448        }
 6449    }
 6450
 6451    pub fn inlay_hints(
 6452        &mut self,
 6453        buffer: Entity<Buffer>,
 6454        range: Range<Anchor>,
 6455        cx: &mut Context<Self>,
 6456    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6457        let range_start = range.start;
 6458        let range_end = range.end;
 6459        let buffer_id = buffer.read(cx).remote_id().into();
 6460        let request = InlayHints { range };
 6461
 6462        if let Some((client, project_id)) = self.upstream_client() {
 6463            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6464                return Task::ready(Ok(Vec::new()));
 6465            }
 6466            let proto_request = proto::InlayHints {
 6467                project_id,
 6468                buffer_id,
 6469                start: Some(serialize_anchor(&range_start)),
 6470                end: Some(serialize_anchor(&range_end)),
 6471                version: serialize_version(&buffer.read(cx).version()),
 6472            };
 6473            cx.spawn(async move |project, cx| {
 6474                let response = client
 6475                    .request(proto_request)
 6476                    .await
 6477                    .context("inlay hints proto request")?;
 6478                LspCommand::response_from_proto(
 6479                    request,
 6480                    response,
 6481                    project.upgrade().context("No project")?,
 6482                    buffer.clone(),
 6483                    cx.clone(),
 6484                )
 6485                .await
 6486                .context("inlay hints proto response conversion")
 6487            })
 6488        } else {
 6489            let lsp_request_task = self.request_lsp(
 6490                buffer.clone(),
 6491                LanguageServerToQuery::FirstCapable,
 6492                request,
 6493                cx,
 6494            );
 6495            cx.spawn(async move |_, cx| {
 6496                buffer
 6497                    .update(cx, |buffer, _| {
 6498                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6499                    })?
 6500                    .await
 6501                    .context("waiting for inlay hint request range edits")?;
 6502                lsp_request_task.await.context("inlay hints LSP request")
 6503            })
 6504        }
 6505    }
 6506
 6507    pub fn pull_diagnostics_for_buffer(
 6508        &mut self,
 6509        buffer: Entity<Buffer>,
 6510        cx: &mut Context<Self>,
 6511    ) -> Task<anyhow::Result<()>> {
 6512        let diagnostics = self.pull_diagnostics(buffer, cx);
 6513        cx.spawn(async move |lsp_store, cx| {
 6514            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6515                return Ok(());
 6516            };
 6517            lsp_store.update(cx, |lsp_store, cx| {
 6518                if lsp_store.as_local().is_none() {
 6519                    return;
 6520                }
 6521
 6522                let mut unchanged_buffers = HashSet::default();
 6523                let mut changed_buffers = HashSet::default();
 6524                let server_diagnostics_updates = diagnostics
 6525                    .into_iter()
 6526                    .filter_map(|diagnostics_set| match diagnostics_set {
 6527                        LspPullDiagnostics::Response {
 6528                            server_id,
 6529                            uri,
 6530                            diagnostics,
 6531                        } => Some((server_id, uri, diagnostics)),
 6532                        LspPullDiagnostics::Default => None,
 6533                    })
 6534                    .fold(
 6535                        HashMap::default(),
 6536                        |mut acc, (server_id, uri, diagnostics)| {
 6537                            let (result_id, diagnostics) = match diagnostics {
 6538                                PulledDiagnostics::Unchanged { result_id } => {
 6539                                    unchanged_buffers.insert(uri.clone());
 6540                                    (Some(result_id), Vec::new())
 6541                                }
 6542                                PulledDiagnostics::Changed {
 6543                                    result_id,
 6544                                    diagnostics,
 6545                                } => {
 6546                                    changed_buffers.insert(uri.clone());
 6547                                    (result_id, diagnostics)
 6548                                }
 6549                            };
 6550                            let disk_based_sources = Cow::Owned(
 6551                                lsp_store
 6552                                    .language_server_adapter_for_id(server_id)
 6553                                    .as_ref()
 6554                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6555                                    .unwrap_or(&[])
 6556                                    .to_vec(),
 6557                            );
 6558                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6559                                DocumentDiagnosticsUpdate {
 6560                                    server_id,
 6561                                    diagnostics: lsp::PublishDiagnosticsParams {
 6562                                        uri,
 6563                                        diagnostics,
 6564                                        version: None,
 6565                                    },
 6566                                    result_id,
 6567                                    disk_based_sources,
 6568                                },
 6569                            );
 6570                            acc
 6571                        },
 6572                    );
 6573
 6574                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6575                    lsp_store
 6576                        .merge_lsp_diagnostics(
 6577                            DiagnosticSourceKind::Pulled,
 6578                            diagnostic_updates,
 6579                            |buffer, old_diagnostic, cx| {
 6580                                File::from_dyn(buffer.file())
 6581                                    .and_then(|file| {
 6582                                        let abs_path = file.as_local()?.abs_path(cx);
 6583                                        lsp::Uri::from_file_path(abs_path).ok()
 6584                                    })
 6585                                    .is_none_or(|buffer_uri| {
 6586                                        unchanged_buffers.contains(&buffer_uri)
 6587                                            || match old_diagnostic.source_kind {
 6588                                                DiagnosticSourceKind::Pulled => {
 6589                                                    !changed_buffers.contains(&buffer_uri)
 6590                                                }
 6591                                                DiagnosticSourceKind::Other
 6592                                                | DiagnosticSourceKind::Pushed => true,
 6593                                            }
 6594                                    })
 6595                            },
 6596                            cx,
 6597                        )
 6598                        .log_err();
 6599                }
 6600            })
 6601        })
 6602    }
 6603
 6604    pub fn document_colors(
 6605        &mut self,
 6606        fetch_strategy: LspFetchStrategy,
 6607        buffer: Entity<Buffer>,
 6608        cx: &mut Context<Self>,
 6609    ) -> Option<DocumentColorTask> {
 6610        let version_queried_for = buffer.read(cx).version();
 6611        let buffer_id = buffer.read(cx).remote_id();
 6612
 6613        match fetch_strategy {
 6614            LspFetchStrategy::IgnoreCache => {}
 6615            LspFetchStrategy::UseCache {
 6616                known_cache_version,
 6617            } => {
 6618                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6619                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6620                {
 6621                    let has_different_servers = self.as_local().is_some_and(|local| {
 6622                        local
 6623                            .buffers_opened_in_servers
 6624                            .get(&buffer_id)
 6625                            .cloned()
 6626                            .unwrap_or_default()
 6627                            != cached_data.colors.keys().copied().collect()
 6628                    });
 6629                    if !has_different_servers {
 6630                        if Some(cached_data.cache_version) == known_cache_version {
 6631                            return None;
 6632                        } else {
 6633                            return Some(
 6634                                Task::ready(Ok(DocumentColors {
 6635                                    colors: cached_data
 6636                                        .colors
 6637                                        .values()
 6638                                        .flatten()
 6639                                        .cloned()
 6640                                        .collect(),
 6641                                    cache_version: Some(cached_data.cache_version),
 6642                                }))
 6643                                .shared(),
 6644                            );
 6645                        }
 6646                    }
 6647                }
 6648            }
 6649        }
 6650
 6651        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6652        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6653            && !version_queried_for.changed_since(updating_for)
 6654        {
 6655            return Some(running_update.clone());
 6656        }
 6657        let query_version_queried_for = version_queried_for.clone();
 6658        let new_task = cx
 6659            .spawn(async move |lsp_store, cx| {
 6660                cx.background_executor()
 6661                    .timer(Duration::from_millis(30))
 6662                    .await;
 6663                let fetched_colors = lsp_store
 6664                    .update(cx, |lsp_store, cx| {
 6665                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6666                    })?
 6667                    .await
 6668                    .context("fetching document colors")
 6669                    .map_err(Arc::new);
 6670                let fetched_colors = match fetched_colors {
 6671                    Ok(fetched_colors) => {
 6672                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6673                            && Some(true)
 6674                                == buffer
 6675                                    .update(cx, |buffer, _| {
 6676                                        buffer.version() != query_version_queried_for
 6677                                    })
 6678                                    .ok()
 6679                        {
 6680                            return Ok(DocumentColors::default());
 6681                        }
 6682                        fetched_colors
 6683                    }
 6684                    Err(e) => {
 6685                        lsp_store
 6686                            .update(cx, |lsp_store, _| {
 6687                                lsp_store
 6688                                    .lsp_document_colors
 6689                                    .entry(buffer_id)
 6690                                    .or_default()
 6691                                    .colors_update = None;
 6692                            })
 6693                            .ok();
 6694                        return Err(e);
 6695                    }
 6696                };
 6697
 6698                lsp_store
 6699                    .update(cx, |lsp_store, _| {
 6700                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6701
 6702                        if let Some(fetched_colors) = fetched_colors {
 6703                            if lsp_data.colors_for_version == query_version_queried_for {
 6704                                lsp_data.colors.extend(fetched_colors);
 6705                                lsp_data.cache_version += 1;
 6706                            } else if !lsp_data
 6707                                .colors_for_version
 6708                                .changed_since(&query_version_queried_for)
 6709                            {
 6710                                lsp_data.colors_for_version = query_version_queried_for;
 6711                                lsp_data.colors = fetched_colors;
 6712                                lsp_data.cache_version += 1;
 6713                            }
 6714                        }
 6715                        lsp_data.colors_update = None;
 6716                        let colors = lsp_data
 6717                            .colors
 6718                            .values()
 6719                            .flatten()
 6720                            .cloned()
 6721                            .collect::<HashSet<_>>();
 6722                        DocumentColors {
 6723                            colors,
 6724                            cache_version: Some(lsp_data.cache_version),
 6725                        }
 6726                    })
 6727                    .map_err(Arc::new)
 6728            })
 6729            .shared();
 6730        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6731        Some(new_task)
 6732    }
 6733
 6734    fn fetch_document_colors_for_buffer(
 6735        &mut self,
 6736        buffer: &Entity<Buffer>,
 6737        cx: &mut Context<Self>,
 6738    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6739        if let Some((client, project_id)) = self.upstream_client() {
 6740            let request = GetDocumentColor {};
 6741            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6742                return Task::ready(Ok(None));
 6743            }
 6744
 6745            let request_task = client.request_lsp(
 6746                project_id,
 6747                LSP_REQUEST_TIMEOUT,
 6748                cx.background_executor().clone(),
 6749                request.to_proto(project_id, buffer.read(cx)),
 6750            );
 6751            let buffer = buffer.clone();
 6752            cx.spawn(async move |lsp_store, cx| {
 6753                let Some(project) = lsp_store.upgrade() else {
 6754                    return Ok(None);
 6755                };
 6756                let colors = join_all(
 6757                    request_task
 6758                        .await
 6759                        .log_err()
 6760                        .flatten()
 6761                        .map(|response| response.payload)
 6762                        .unwrap_or_default()
 6763                        .into_iter()
 6764                        .map(|color_response| {
 6765                            let response = request.response_from_proto(
 6766                                color_response.response,
 6767                                project.clone(),
 6768                                buffer.clone(),
 6769                                cx.clone(),
 6770                            );
 6771                            async move {
 6772                                (
 6773                                    LanguageServerId::from_proto(color_response.server_id),
 6774                                    response.await.log_err().unwrap_or_default(),
 6775                                )
 6776                            }
 6777                        }),
 6778                )
 6779                .await
 6780                .into_iter()
 6781                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6782                    acc.entry(server_id)
 6783                        .or_insert_with(HashSet::default)
 6784                        .extend(colors);
 6785                    acc
 6786                });
 6787                Ok(Some(colors))
 6788            })
 6789        } else {
 6790            let document_colors_task =
 6791                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6792            cx.background_spawn(async move {
 6793                Ok(Some(
 6794                    document_colors_task
 6795                        .await
 6796                        .into_iter()
 6797                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6798                            acc.entry(server_id)
 6799                                .or_insert_with(HashSet::default)
 6800                                .extend(colors);
 6801                            acc
 6802                        })
 6803                        .into_iter()
 6804                        .collect(),
 6805                ))
 6806            })
 6807        }
 6808    }
 6809
 6810    pub fn signature_help<T: ToPointUtf16>(
 6811        &mut self,
 6812        buffer: &Entity<Buffer>,
 6813        position: T,
 6814        cx: &mut Context<Self>,
 6815    ) -> Task<Option<Vec<SignatureHelp>>> {
 6816        let position = position.to_point_utf16(buffer.read(cx));
 6817
 6818        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6819            let request = GetSignatureHelp { position };
 6820            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6821                return Task::ready(None);
 6822            }
 6823            let request_task = client.request_lsp(
 6824                upstream_project_id,
 6825                LSP_REQUEST_TIMEOUT,
 6826                cx.background_executor().clone(),
 6827                request.to_proto(upstream_project_id, buffer.read(cx)),
 6828            );
 6829            let buffer = buffer.clone();
 6830            cx.spawn(async move |weak_project, cx| {
 6831                let project = weak_project.upgrade()?;
 6832                let signatures = join_all(
 6833                    request_task
 6834                        .await
 6835                        .log_err()
 6836                        .flatten()
 6837                        .map(|response| response.payload)
 6838                        .unwrap_or_default()
 6839                        .into_iter()
 6840                        .map(|response| {
 6841                            let response = GetSignatureHelp { position }.response_from_proto(
 6842                                response.response,
 6843                                project.clone(),
 6844                                buffer.clone(),
 6845                                cx.clone(),
 6846                            );
 6847                            async move { response.await.log_err().flatten() }
 6848                        }),
 6849                )
 6850                .await
 6851                .into_iter()
 6852                .flatten()
 6853                .collect();
 6854                Some(signatures)
 6855            })
 6856        } else {
 6857            let all_actions_task = self.request_multiple_lsp_locally(
 6858                buffer,
 6859                Some(position),
 6860                GetSignatureHelp { position },
 6861                cx,
 6862            );
 6863            cx.background_spawn(async move {
 6864                Some(
 6865                    all_actions_task
 6866                        .await
 6867                        .into_iter()
 6868                        .flat_map(|(_, actions)| actions)
 6869                        .collect::<Vec<_>>(),
 6870                )
 6871            })
 6872        }
 6873    }
 6874
 6875    pub fn hover(
 6876        &mut self,
 6877        buffer: &Entity<Buffer>,
 6878        position: PointUtf16,
 6879        cx: &mut Context<Self>,
 6880    ) -> Task<Option<Vec<Hover>>> {
 6881        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6882            let request = GetHover { position };
 6883            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6884                return Task::ready(None);
 6885            }
 6886            let request_task = client.request_lsp(
 6887                upstream_project_id,
 6888                LSP_REQUEST_TIMEOUT,
 6889                cx.background_executor().clone(),
 6890                request.to_proto(upstream_project_id, buffer.read(cx)),
 6891            );
 6892            let buffer = buffer.clone();
 6893            cx.spawn(async move |weak_project, cx| {
 6894                let project = weak_project.upgrade()?;
 6895                let hovers = join_all(
 6896                    request_task
 6897                        .await
 6898                        .log_err()
 6899                        .flatten()
 6900                        .map(|response| response.payload)
 6901                        .unwrap_or_default()
 6902                        .into_iter()
 6903                        .map(|response| {
 6904                            let response = GetHover { position }.response_from_proto(
 6905                                response.response,
 6906                                project.clone(),
 6907                                buffer.clone(),
 6908                                cx.clone(),
 6909                            );
 6910                            async move {
 6911                                response
 6912                                    .await
 6913                                    .log_err()
 6914                                    .flatten()
 6915                                    .and_then(remove_empty_hover_blocks)
 6916                            }
 6917                        }),
 6918                )
 6919                .await
 6920                .into_iter()
 6921                .flatten()
 6922                .collect();
 6923                Some(hovers)
 6924            })
 6925        } else {
 6926            let all_actions_task = self.request_multiple_lsp_locally(
 6927                buffer,
 6928                Some(position),
 6929                GetHover { position },
 6930                cx,
 6931            );
 6932            cx.background_spawn(async move {
 6933                Some(
 6934                    all_actions_task
 6935                        .await
 6936                        .into_iter()
 6937                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6938                        .collect::<Vec<Hover>>(),
 6939                )
 6940            })
 6941        }
 6942    }
 6943
 6944    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6945        let language_registry = self.languages.clone();
 6946
 6947        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6948            let request = upstream_client.request(proto::GetProjectSymbols {
 6949                project_id: *project_id,
 6950                query: query.to_string(),
 6951            });
 6952            cx.foreground_executor().spawn(async move {
 6953                let response = request.await?;
 6954                let mut symbols = Vec::new();
 6955                let core_symbols = response
 6956                    .symbols
 6957                    .into_iter()
 6958                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6959                    .collect::<Vec<_>>();
 6960                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6961                    .await;
 6962                Ok(symbols)
 6963            })
 6964        } else if let Some(local) = self.as_local() {
 6965            struct WorkspaceSymbolsResult {
 6966                server_id: LanguageServerId,
 6967                lsp_adapter: Arc<CachedLspAdapter>,
 6968                worktree: WeakEntity<Worktree>,
 6969                worktree_abs_path: Arc<Path>,
 6970                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6971            }
 6972
 6973            let mut requests = Vec::new();
 6974            let mut requested_servers = BTreeSet::new();
 6975            for (seed, state) in local.language_server_ids.iter() {
 6976                let Some(worktree_handle) = self
 6977                    .worktree_store
 6978                    .read(cx)
 6979                    .worktree_for_id(seed.worktree_id, cx)
 6980                else {
 6981                    continue;
 6982                };
 6983                let worktree = worktree_handle.read(cx);
 6984                if !worktree.is_visible() {
 6985                    continue;
 6986                }
 6987
 6988                if !requested_servers.insert(state.id) {
 6989                    continue;
 6990                }
 6991
 6992                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 6993                    Some(LanguageServerState::Running {
 6994                        adapter, server, ..
 6995                    }) => (adapter.clone(), server),
 6996
 6997                    _ => continue,
 6998                };
 6999                let supports_workspace_symbol_request =
 7000                    match server.capabilities().workspace_symbol_provider {
 7001                        Some(OneOf::Left(supported)) => supported,
 7002                        Some(OneOf::Right(_)) => true,
 7003                        None => false,
 7004                    };
 7005                if !supports_workspace_symbol_request {
 7006                    continue;
 7007                }
 7008                let worktree_abs_path = worktree.abs_path().clone();
 7009                let worktree_handle = worktree_handle.clone();
 7010                let server_id = server.server_id();
 7011                requests.push(
 7012                        server
 7013                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7014                                lsp::WorkspaceSymbolParams {
 7015                                    query: query.to_string(),
 7016                                    ..Default::default()
 7017                                },
 7018                            )
 7019                            .map(move |response| {
 7020                                let lsp_symbols = response.into_response()
 7021                                    .context("workspace symbols request")
 7022                                    .log_err()
 7023                                    .flatten()
 7024                                    .map(|symbol_response| match symbol_response {
 7025                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7026                                            flat_responses.into_iter().map(|lsp_symbol| {
 7027                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7028                                            }).collect::<Vec<_>>()
 7029                                        }
 7030                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7031                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7032                                                let location = match lsp_symbol.location {
 7033                                                    OneOf::Left(location) => location,
 7034                                                    OneOf::Right(_) => {
 7035                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7036                                                        return None
 7037                                                    }
 7038                                                };
 7039                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7040                                            }).collect::<Vec<_>>()
 7041                                        }
 7042                                    }).unwrap_or_default();
 7043
 7044                                WorkspaceSymbolsResult {
 7045                                    server_id,
 7046                                    lsp_adapter,
 7047                                    worktree: worktree_handle.downgrade(),
 7048                                    worktree_abs_path,
 7049                                    lsp_symbols,
 7050                                }
 7051                            }),
 7052                    );
 7053            }
 7054
 7055            cx.spawn(async move |this, cx| {
 7056                let responses = futures::future::join_all(requests).await;
 7057                let this = match this.upgrade() {
 7058                    Some(this) => this,
 7059                    None => return Ok(Vec::new()),
 7060                };
 7061
 7062                let mut symbols = Vec::new();
 7063                for result in responses {
 7064                    let core_symbols = this.update(cx, |this, cx| {
 7065                        result
 7066                            .lsp_symbols
 7067                            .into_iter()
 7068                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7069                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7070                                let source_worktree = result.worktree.upgrade()?;
 7071                                let source_worktree_id = source_worktree.read(cx).id();
 7072
 7073                                let path;
 7074                                let worktree;
 7075                                if let Some((tree, rel_path)) =
 7076                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7077                                {
 7078                                    worktree = tree;
 7079                                    path = rel_path;
 7080                                } else {
 7081                                    worktree = source_worktree;
 7082                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7083                                }
 7084
 7085                                let worktree_id = worktree.read(cx).id();
 7086                                let project_path = ProjectPath {
 7087                                    worktree_id,
 7088                                    path: path.into(),
 7089                                };
 7090                                let signature = this.symbol_signature(&project_path);
 7091                                Some(CoreSymbol {
 7092                                    source_language_server_id: result.server_id,
 7093                                    language_server_name: result.lsp_adapter.name.clone(),
 7094                                    source_worktree_id,
 7095                                    path: project_path,
 7096                                    kind: symbol_kind,
 7097                                    name: symbol_name,
 7098                                    range: range_from_lsp(symbol_location.range),
 7099                                    signature,
 7100                                })
 7101                            })
 7102                            .collect()
 7103                    })?;
 7104
 7105                    populate_labels_for_symbols(
 7106                        core_symbols,
 7107                        &language_registry,
 7108                        Some(result.lsp_adapter),
 7109                        &mut symbols,
 7110                    )
 7111                    .await;
 7112                }
 7113
 7114                Ok(symbols)
 7115            })
 7116        } else {
 7117            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7118        }
 7119    }
 7120
 7121    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7122        let mut summary = DiagnosticSummary::default();
 7123        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7124            summary.error_count += path_summary.error_count;
 7125            summary.warning_count += path_summary.warning_count;
 7126        }
 7127        summary
 7128    }
 7129
 7130    pub fn diagnostic_summaries<'a>(
 7131        &'a self,
 7132        include_ignored: bool,
 7133        cx: &'a App,
 7134    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7135        self.worktree_store
 7136            .read(cx)
 7137            .visible_worktrees(cx)
 7138            .filter_map(|worktree| {
 7139                let worktree = worktree.read(cx);
 7140                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7141            })
 7142            .flat_map(move |(worktree, summaries)| {
 7143                let worktree_id = worktree.id();
 7144                summaries
 7145                    .iter()
 7146                    .filter(move |(path, _)| {
 7147                        include_ignored
 7148                            || worktree
 7149                                .entry_for_path(path.as_ref())
 7150                                .is_some_and(|entry| !entry.is_ignored)
 7151                    })
 7152                    .flat_map(move |(path, summaries)| {
 7153                        summaries.iter().map(move |(server_id, summary)| {
 7154                            (
 7155                                ProjectPath {
 7156                                    worktree_id,
 7157                                    path: path.clone(),
 7158                                },
 7159                                *server_id,
 7160                                *summary,
 7161                            )
 7162                        })
 7163                    })
 7164            })
 7165    }
 7166
 7167    pub fn on_buffer_edited(
 7168        &mut self,
 7169        buffer: Entity<Buffer>,
 7170        cx: &mut Context<Self>,
 7171    ) -> Option<()> {
 7172        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7173            Some(
 7174                self.as_local()?
 7175                    .language_servers_for_buffer(buffer, cx)
 7176                    .map(|i| i.1.clone())
 7177                    .collect(),
 7178            )
 7179        })?;
 7180
 7181        let buffer = buffer.read(cx);
 7182        let file = File::from_dyn(buffer.file())?;
 7183        let abs_path = file.as_local()?.abs_path(cx);
 7184        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7185        let next_snapshot = buffer.text_snapshot();
 7186        for language_server in language_servers {
 7187            let language_server = language_server.clone();
 7188
 7189            let buffer_snapshots = self
 7190                .as_local_mut()
 7191                .unwrap()
 7192                .buffer_snapshots
 7193                .get_mut(&buffer.remote_id())
 7194                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7195            let previous_snapshot = buffer_snapshots.last()?;
 7196
 7197            let build_incremental_change = || {
 7198                buffer
 7199                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7200                        previous_snapshot.snapshot.version(),
 7201                    )
 7202                    .map(|edit| {
 7203                        let edit_start = edit.new.start.0;
 7204                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7205                        let new_text = next_snapshot
 7206                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7207                            .collect();
 7208                        lsp::TextDocumentContentChangeEvent {
 7209                            range: Some(lsp::Range::new(
 7210                                point_to_lsp(edit_start),
 7211                                point_to_lsp(edit_end),
 7212                            )),
 7213                            range_length: None,
 7214                            text: new_text,
 7215                        }
 7216                    })
 7217                    .collect()
 7218            };
 7219
 7220            let document_sync_kind = language_server
 7221                .capabilities()
 7222                .text_document_sync
 7223                .as_ref()
 7224                .and_then(|sync| match sync {
 7225                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7226                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7227                });
 7228
 7229            let content_changes: Vec<_> = match document_sync_kind {
 7230                Some(lsp::TextDocumentSyncKind::FULL) => {
 7231                    vec![lsp::TextDocumentContentChangeEvent {
 7232                        range: None,
 7233                        range_length: None,
 7234                        text: next_snapshot.text(),
 7235                    }]
 7236                }
 7237                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7238                _ => {
 7239                    #[cfg(any(test, feature = "test-support"))]
 7240                    {
 7241                        build_incremental_change()
 7242                    }
 7243
 7244                    #[cfg(not(any(test, feature = "test-support")))]
 7245                    {
 7246                        continue;
 7247                    }
 7248                }
 7249            };
 7250
 7251            let next_version = previous_snapshot.version + 1;
 7252            buffer_snapshots.push(LspBufferSnapshot {
 7253                version: next_version,
 7254                snapshot: next_snapshot.clone(),
 7255            });
 7256
 7257            language_server
 7258                .notify::<lsp::notification::DidChangeTextDocument>(
 7259                    &lsp::DidChangeTextDocumentParams {
 7260                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7261                            uri.clone(),
 7262                            next_version,
 7263                        ),
 7264                        content_changes,
 7265                    },
 7266                )
 7267                .ok();
 7268            self.pull_workspace_diagnostics(language_server.server_id());
 7269        }
 7270
 7271        None
 7272    }
 7273
 7274    pub fn on_buffer_saved(
 7275        &mut self,
 7276        buffer: Entity<Buffer>,
 7277        cx: &mut Context<Self>,
 7278    ) -> Option<()> {
 7279        let file = File::from_dyn(buffer.read(cx).file())?;
 7280        let worktree_id = file.worktree_id(cx);
 7281        let abs_path = file.as_local()?.abs_path(cx);
 7282        let text_document = lsp::TextDocumentIdentifier {
 7283            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7284        };
 7285        let local = self.as_local()?;
 7286
 7287        for server in local.language_servers_for_worktree(worktree_id) {
 7288            if let Some(include_text) = include_text(server.as_ref()) {
 7289                let text = if include_text {
 7290                    Some(buffer.read(cx).text())
 7291                } else {
 7292                    None
 7293                };
 7294                server
 7295                    .notify::<lsp::notification::DidSaveTextDocument>(
 7296                        &lsp::DidSaveTextDocumentParams {
 7297                            text_document: text_document.clone(),
 7298                            text,
 7299                        },
 7300                    )
 7301                    .ok();
 7302            }
 7303        }
 7304
 7305        let language_servers = buffer.update(cx, |buffer, cx| {
 7306            local.language_server_ids_for_buffer(buffer, cx)
 7307        });
 7308        for language_server_id in language_servers {
 7309            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7310        }
 7311
 7312        None
 7313    }
 7314
 7315    async fn refresh_workspace_configurations(
 7316        lsp_store: &WeakEntity<Self>,
 7317        fs: Arc<dyn Fs>,
 7318        cx: &mut AsyncApp,
 7319    ) {
 7320        maybe!(async move {
 7321            let mut refreshed_servers = HashSet::default();
 7322            let servers = lsp_store
 7323                .update(cx, |lsp_store, cx| {
 7324                    let local = lsp_store.as_local()?;
 7325
 7326                    let servers = local
 7327                        .language_server_ids
 7328                        .iter()
 7329                        .filter_map(|(seed, state)| {
 7330                            let worktree = lsp_store
 7331                                .worktree_store
 7332                                .read(cx)
 7333                                .worktree_for_id(seed.worktree_id, cx);
 7334                            let delegate: Arc<dyn LspAdapterDelegate> =
 7335                                worktree.map(|worktree| {
 7336                                    LocalLspAdapterDelegate::new(
 7337                                        local.languages.clone(),
 7338                                        &local.environment,
 7339                                        cx.weak_entity(),
 7340                                        &worktree,
 7341                                        local.http_client.clone(),
 7342                                        local.fs.clone(),
 7343                                        cx,
 7344                                    )
 7345                                })?;
 7346                            let server_id = state.id;
 7347
 7348                            let states = local.language_servers.get(&server_id)?;
 7349
 7350                            match states {
 7351                                LanguageServerState::Starting { .. } => None,
 7352                                LanguageServerState::Running {
 7353                                    adapter, server, ..
 7354                                } => {
 7355                                    let fs = fs.clone();
 7356
 7357                                    let adapter = adapter.clone();
 7358                                    let server = server.clone();
 7359                                    refreshed_servers.insert(server.name());
 7360                                    let toolchain = seed.toolchain.clone();
 7361                                    Some(cx.spawn(async move |_, cx| {
 7362                                        let settings =
 7363                                            LocalLspStore::workspace_configuration_for_adapter(
 7364                                                adapter.adapter.clone(),
 7365                                                fs.as_ref(),
 7366                                                &delegate,
 7367                                                toolchain,
 7368                                                cx,
 7369                                            )
 7370                                            .await
 7371                                            .ok()?;
 7372                                        server
 7373                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7374                                                &lsp::DidChangeConfigurationParams { settings },
 7375                                            )
 7376                                            .ok()?;
 7377                                        Some(())
 7378                                    }))
 7379                                }
 7380                            }
 7381                        })
 7382                        .collect::<Vec<_>>();
 7383
 7384                    Some(servers)
 7385                })
 7386                .ok()
 7387                .flatten()?;
 7388
 7389            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7390            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7391            // to stop and unregister its language server wrapper.
 7392            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7393            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7394            let _: Vec<Option<()>> = join_all(servers).await;
 7395
 7396            Some(())
 7397        })
 7398        .await;
 7399    }
 7400
 7401    fn maintain_workspace_config(
 7402        fs: Arc<dyn Fs>,
 7403        external_refresh_requests: watch::Receiver<()>,
 7404        cx: &mut Context<Self>,
 7405    ) -> Task<Result<()>> {
 7406        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7407        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7408
 7409        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7410            *settings_changed_tx.borrow_mut() = ();
 7411        });
 7412
 7413        let mut joint_future =
 7414            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7415        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7416        // - 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).
 7417        // - 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.
 7418        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7419        // - 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,
 7420        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7421        cx.spawn(async move |this, cx| {
 7422            while let Some(()) = joint_future.next().await {
 7423                this.update(cx, |this, cx| {
 7424                    this.refresh_server_tree(cx);
 7425                })
 7426                .ok();
 7427
 7428                Self::refresh_workspace_configurations(&this, fs.clone(), cx).await;
 7429            }
 7430
 7431            drop(settings_observation);
 7432            anyhow::Ok(())
 7433        })
 7434    }
 7435
 7436    pub fn language_servers_for_local_buffer<'a>(
 7437        &'a self,
 7438        buffer: &Buffer,
 7439        cx: &mut App,
 7440    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7441        let local = self.as_local();
 7442        let language_server_ids = local
 7443            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7444            .unwrap_or_default();
 7445
 7446        language_server_ids
 7447            .into_iter()
 7448            .filter_map(
 7449                move |server_id| match local?.language_servers.get(&server_id)? {
 7450                    LanguageServerState::Running {
 7451                        adapter, server, ..
 7452                    } => Some((adapter, server)),
 7453                    _ => None,
 7454                },
 7455            )
 7456    }
 7457
 7458    pub fn language_server_for_local_buffer<'a>(
 7459        &'a self,
 7460        buffer: &'a Buffer,
 7461        server_id: LanguageServerId,
 7462        cx: &'a mut App,
 7463    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7464        self.as_local()?
 7465            .language_servers_for_buffer(buffer, cx)
 7466            .find(|(_, s)| s.server_id() == server_id)
 7467    }
 7468
 7469    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7470        self.diagnostic_summaries.remove(&id_to_remove);
 7471        if let Some(local) = self.as_local_mut() {
 7472            let to_remove = local.remove_worktree(id_to_remove, cx);
 7473            for server in to_remove {
 7474                self.language_server_statuses.remove(&server);
 7475            }
 7476        }
 7477    }
 7478
 7479    pub fn shared(
 7480        &mut self,
 7481        project_id: u64,
 7482        downstream_client: AnyProtoClient,
 7483        _: &mut Context<Self>,
 7484    ) {
 7485        self.downstream_client = Some((downstream_client.clone(), project_id));
 7486
 7487        for (server_id, status) in &self.language_server_statuses {
 7488            if let Some(server) = self.language_server_for_id(*server_id) {
 7489                downstream_client
 7490                    .send(proto::StartLanguageServer {
 7491                        project_id,
 7492                        server: Some(proto::LanguageServer {
 7493                            id: server_id.to_proto(),
 7494                            name: status.name.to_string(),
 7495                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7496                        }),
 7497                        capabilities: serde_json::to_string(&server.capabilities())
 7498                            .expect("serializing server LSP capabilities"),
 7499                    })
 7500                    .log_err();
 7501            }
 7502        }
 7503    }
 7504
 7505    pub fn disconnected_from_host(&mut self) {
 7506        self.downstream_client.take();
 7507    }
 7508
 7509    pub fn disconnected_from_ssh_remote(&mut self) {
 7510        if let LspStoreMode::Remote(RemoteLspStore {
 7511            upstream_client, ..
 7512        }) = &mut self.mode
 7513        {
 7514            upstream_client.take();
 7515        }
 7516    }
 7517
 7518    pub(crate) fn set_language_server_statuses_from_proto(
 7519        &mut self,
 7520        project: WeakEntity<Project>,
 7521        language_servers: Vec<proto::LanguageServer>,
 7522        server_capabilities: Vec<String>,
 7523        cx: &mut Context<Self>,
 7524    ) {
 7525        let lsp_logs = cx
 7526            .try_global::<GlobalLogStore>()
 7527            .map(|lsp_store| lsp_store.0.clone());
 7528
 7529        self.language_server_statuses = language_servers
 7530            .into_iter()
 7531            .zip(server_capabilities)
 7532            .map(|(server, server_capabilities)| {
 7533                let server_id = LanguageServerId(server.id as usize);
 7534                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7535                    self.lsp_server_capabilities
 7536                        .insert(server_id, server_capabilities);
 7537                }
 7538
 7539                let name = LanguageServerName::from_proto(server.name);
 7540                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7541
 7542                if let Some(lsp_logs) = &lsp_logs {
 7543                    lsp_logs.update(cx, |lsp_logs, cx| {
 7544                        lsp_logs.add_language_server(
 7545                            // Only remote clients get their language servers set from proto
 7546                            LanguageServerKind::Remote {
 7547                                project: project.clone(),
 7548                            },
 7549                            server_id,
 7550                            Some(name.clone()),
 7551                            worktree,
 7552                            None,
 7553                            cx,
 7554                        );
 7555                    });
 7556                }
 7557
 7558                (
 7559                    server_id,
 7560                    LanguageServerStatus {
 7561                        name,
 7562                        pending_work: Default::default(),
 7563                        has_pending_diagnostic_updates: false,
 7564                        progress_tokens: Default::default(),
 7565                        worktree,
 7566                    },
 7567                )
 7568            })
 7569            .collect();
 7570    }
 7571
 7572    #[cfg(test)]
 7573    pub fn update_diagnostic_entries(
 7574        &mut self,
 7575        server_id: LanguageServerId,
 7576        abs_path: PathBuf,
 7577        result_id: Option<String>,
 7578        version: Option<i32>,
 7579        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7580        cx: &mut Context<Self>,
 7581    ) -> anyhow::Result<()> {
 7582        self.merge_diagnostic_entries(
 7583            vec![DocumentDiagnosticsUpdate {
 7584                diagnostics: DocumentDiagnostics {
 7585                    diagnostics,
 7586                    document_abs_path: abs_path,
 7587                    version,
 7588                },
 7589                result_id,
 7590                server_id,
 7591                disk_based_sources: Cow::Borrowed(&[]),
 7592            }],
 7593            |_, _, _| false,
 7594            cx,
 7595        )?;
 7596        Ok(())
 7597    }
 7598
 7599    pub fn merge_diagnostic_entries<'a>(
 7600        &mut self,
 7601        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7602        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7603        cx: &mut Context<Self>,
 7604    ) -> anyhow::Result<()> {
 7605        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7606        let mut updated_diagnostics_paths = HashMap::default();
 7607        for mut update in diagnostic_updates {
 7608            let abs_path = &update.diagnostics.document_abs_path;
 7609            let server_id = update.server_id;
 7610            let Some((worktree, relative_path)) =
 7611                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7612            else {
 7613                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7614                return Ok(());
 7615            };
 7616
 7617            let worktree_id = worktree.read(cx).id();
 7618            let project_path = ProjectPath {
 7619                worktree_id,
 7620                path: relative_path.into(),
 7621            };
 7622
 7623            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7624                let snapshot = buffer_handle.read(cx).snapshot();
 7625                let buffer = buffer_handle.read(cx);
 7626                let reused_diagnostics = buffer
 7627                    .buffer_diagnostics(Some(server_id))
 7628                    .iter()
 7629                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 7630                    .map(|v| {
 7631                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7632                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7633                        DiagnosticEntry {
 7634                            range: start..end,
 7635                            diagnostic: v.diagnostic.clone(),
 7636                        }
 7637                    })
 7638                    .collect::<Vec<_>>();
 7639
 7640                self.as_local_mut()
 7641                    .context("cannot merge diagnostics on a remote LspStore")?
 7642                    .update_buffer_diagnostics(
 7643                        &buffer_handle,
 7644                        server_id,
 7645                        update.result_id,
 7646                        update.diagnostics.version,
 7647                        update.diagnostics.diagnostics.clone(),
 7648                        reused_diagnostics.clone(),
 7649                        cx,
 7650                    )?;
 7651
 7652                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7653            }
 7654
 7655            let updated = worktree.update(cx, |worktree, cx| {
 7656                self.update_worktree_diagnostics(
 7657                    worktree.id(),
 7658                    server_id,
 7659                    project_path.path.clone(),
 7660                    update.diagnostics.diagnostics,
 7661                    cx,
 7662                )
 7663            })?;
 7664            match updated {
 7665                ControlFlow::Continue(new_summary) => {
 7666                    if let Some((project_id, new_summary)) = new_summary {
 7667                        match &mut diagnostics_summary {
 7668                            Some(diagnostics_summary) => {
 7669                                diagnostics_summary
 7670                                    .more_summaries
 7671                                    .push(proto::DiagnosticSummary {
 7672                                        path: project_path.path.as_ref().to_proto(),
 7673                                        language_server_id: server_id.0 as u64,
 7674                                        error_count: new_summary.error_count,
 7675                                        warning_count: new_summary.warning_count,
 7676                                    })
 7677                            }
 7678                            None => {
 7679                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7680                                    project_id,
 7681                                    worktree_id: worktree_id.to_proto(),
 7682                                    summary: Some(proto::DiagnosticSummary {
 7683                                        path: project_path.path.as_ref().to_proto(),
 7684                                        language_server_id: server_id.0 as u64,
 7685                                        error_count: new_summary.error_count,
 7686                                        warning_count: new_summary.warning_count,
 7687                                    }),
 7688                                    more_summaries: Vec::new(),
 7689                                })
 7690                            }
 7691                        }
 7692                    }
 7693                    updated_diagnostics_paths
 7694                        .entry(server_id)
 7695                        .or_insert_with(Vec::new)
 7696                        .push(project_path);
 7697                }
 7698                ControlFlow::Break(()) => {}
 7699            }
 7700        }
 7701
 7702        if let Some((diagnostics_summary, (downstream_client, _))) =
 7703            diagnostics_summary.zip(self.downstream_client.as_ref())
 7704        {
 7705            downstream_client.send(diagnostics_summary).log_err();
 7706        }
 7707        for (server_id, paths) in updated_diagnostics_paths {
 7708            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7709        }
 7710        Ok(())
 7711    }
 7712
 7713    fn update_worktree_diagnostics(
 7714        &mut self,
 7715        worktree_id: WorktreeId,
 7716        server_id: LanguageServerId,
 7717        path_in_worktree: Arc<Path>,
 7718        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7719        _: &mut Context<Worktree>,
 7720    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7721        let local = match &mut self.mode {
 7722            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7723            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7724        };
 7725
 7726        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7727        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7728        let summaries_by_server_id = summaries_for_tree
 7729            .entry(path_in_worktree.clone())
 7730            .or_default();
 7731
 7732        let old_summary = summaries_by_server_id
 7733            .remove(&server_id)
 7734            .unwrap_or_default();
 7735
 7736        let new_summary = DiagnosticSummary::new(&diagnostics);
 7737        if new_summary.is_empty() {
 7738            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7739            {
 7740                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7741                    diagnostics_by_server_id.remove(ix);
 7742                }
 7743                if diagnostics_by_server_id.is_empty() {
 7744                    diagnostics_for_tree.remove(&path_in_worktree);
 7745                }
 7746            }
 7747        } else {
 7748            summaries_by_server_id.insert(server_id, new_summary);
 7749            let diagnostics_by_server_id = diagnostics_for_tree
 7750                .entry(path_in_worktree.clone())
 7751                .or_default();
 7752            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7753                Ok(ix) => {
 7754                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7755                }
 7756                Err(ix) => {
 7757                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7758                }
 7759            }
 7760        }
 7761
 7762        if !old_summary.is_empty() || !new_summary.is_empty() {
 7763            if let Some((_, project_id)) = &self.downstream_client {
 7764                Ok(ControlFlow::Continue(Some((
 7765                    *project_id,
 7766                    proto::DiagnosticSummary {
 7767                        path: path_in_worktree.to_proto(),
 7768                        language_server_id: server_id.0 as u64,
 7769                        error_count: new_summary.error_count as u32,
 7770                        warning_count: new_summary.warning_count as u32,
 7771                    },
 7772                ))))
 7773            } else {
 7774                Ok(ControlFlow::Continue(None))
 7775            }
 7776        } else {
 7777            Ok(ControlFlow::Break(()))
 7778        }
 7779    }
 7780
 7781    pub fn open_buffer_for_symbol(
 7782        &mut self,
 7783        symbol: &Symbol,
 7784        cx: &mut Context<Self>,
 7785    ) -> Task<Result<Entity<Buffer>>> {
 7786        if let Some((client, project_id)) = self.upstream_client() {
 7787            let request = client.request(proto::OpenBufferForSymbol {
 7788                project_id,
 7789                symbol: Some(Self::serialize_symbol(symbol)),
 7790            });
 7791            cx.spawn(async move |this, cx| {
 7792                let response = request.await?;
 7793                let buffer_id = BufferId::new(response.buffer_id)?;
 7794                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7795                    .await
 7796            })
 7797        } else if let Some(local) = self.as_local() {
 7798            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7799                seed.worktree_id == symbol.source_worktree_id
 7800                    && state.id == symbol.source_language_server_id
 7801                    && symbol.language_server_name == seed.name
 7802            });
 7803            if !is_valid {
 7804                return Task::ready(Err(anyhow!(
 7805                    "language server for worktree and language not found"
 7806                )));
 7807            };
 7808
 7809            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7810                .worktree_store
 7811                .read(cx)
 7812                .worktree_for_id(symbol.path.worktree_id, cx)
 7813                .map(|worktree| worktree.read(cx).abs_path())
 7814            {
 7815                worktree_abs_path
 7816            } else {
 7817                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7818            };
 7819
 7820            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7821            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 7822                uri
 7823            } else {
 7824                return Task::ready(Err(anyhow!("invalid symbol path")));
 7825            };
 7826
 7827            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7828        } else {
 7829            Task::ready(Err(anyhow!("no upstream client or local store")))
 7830        }
 7831    }
 7832
 7833    pub(crate) fn open_local_buffer_via_lsp(
 7834        &mut self,
 7835        abs_path: lsp::Uri,
 7836        language_server_id: LanguageServerId,
 7837        cx: &mut Context<Self>,
 7838    ) -> Task<Result<Entity<Buffer>>> {
 7839        cx.spawn(async move |lsp_store, cx| {
 7840            // Escape percent-encoded string.
 7841            let current_scheme = abs_path.scheme().to_owned();
 7842            // Uri is immutable, so we can't modify the scheme
 7843
 7844            let abs_path = abs_path
 7845                .to_file_path()
 7846                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7847            let p = abs_path.clone();
 7848            let yarn_worktree = lsp_store
 7849                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7850                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7851                        cx.spawn(async move |this, cx| {
 7852                            let t = this
 7853                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7854                                .ok()?;
 7855                            t.await
 7856                        })
 7857                    }),
 7858                    None => Task::ready(None),
 7859                })?
 7860                .await;
 7861            let (worktree_root_target, known_relative_path) =
 7862                if let Some((zip_root, relative_path)) = yarn_worktree {
 7863                    (zip_root, Some(relative_path))
 7864                } else {
 7865                    (Arc::<Path>::from(abs_path.as_path()), None)
 7866                };
 7867            let (worktree, relative_path) = if let Some(result) =
 7868                lsp_store.update(cx, |lsp_store, cx| {
 7869                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7870                        worktree_store.find_worktree(&worktree_root_target, cx)
 7871                    })
 7872                })? {
 7873                let relative_path =
 7874                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7875                (result.0, relative_path)
 7876            } else {
 7877                let worktree = lsp_store
 7878                    .update(cx, |lsp_store, cx| {
 7879                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7880                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7881                        })
 7882                    })?
 7883                    .await?;
 7884                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7885                    lsp_store
 7886                        .update(cx, |lsp_store, cx| {
 7887                            if let Some(local) = lsp_store.as_local_mut() {
 7888                                local.register_language_server_for_invisible_worktree(
 7889                                    &worktree,
 7890                                    language_server_id,
 7891                                    cx,
 7892                                )
 7893                            }
 7894                        })
 7895                        .ok();
 7896                }
 7897                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7898                let relative_path = if let Some(known_path) = known_relative_path {
 7899                    known_path
 7900                } else {
 7901                    abs_path.strip_prefix(worktree_root)?.into()
 7902                };
 7903                (worktree, relative_path)
 7904            };
 7905            let project_path = ProjectPath {
 7906                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7907                path: relative_path,
 7908            };
 7909            lsp_store
 7910                .update(cx, |lsp_store, cx| {
 7911                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7912                        buffer_store.open_buffer(project_path, cx)
 7913                    })
 7914                })?
 7915                .await
 7916        })
 7917    }
 7918
 7919    fn request_multiple_lsp_locally<P, R>(
 7920        &mut self,
 7921        buffer: &Entity<Buffer>,
 7922        position: Option<P>,
 7923        request: R,
 7924        cx: &mut Context<Self>,
 7925    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7926    where
 7927        P: ToOffset,
 7928        R: LspCommand + Clone,
 7929        <R::LspRequest as lsp::request::Request>::Result: Send,
 7930        <R::LspRequest as lsp::request::Request>::Params: Send,
 7931    {
 7932        let Some(local) = self.as_local() else {
 7933            return Task::ready(Vec::new());
 7934        };
 7935
 7936        let snapshot = buffer.read(cx).snapshot();
 7937        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7938
 7939        let server_ids = buffer.update(cx, |buffer, cx| {
 7940            local
 7941                .language_servers_for_buffer(buffer, cx)
 7942                .filter(|(adapter, _)| {
 7943                    scope
 7944                        .as_ref()
 7945                        .map(|scope| scope.language_allowed(&adapter.name))
 7946                        .unwrap_or(true)
 7947                })
 7948                .map(|(_, server)| server.server_id())
 7949                .filter(|server_id| {
 7950                    self.as_local().is_none_or(|local| {
 7951                        local
 7952                            .buffers_opened_in_servers
 7953                            .get(&snapshot.remote_id())
 7954                            .is_some_and(|servers| servers.contains(server_id))
 7955                    })
 7956                })
 7957                .collect::<Vec<_>>()
 7958        });
 7959
 7960        let mut response_results = server_ids
 7961            .into_iter()
 7962            .map(|server_id| {
 7963                let task = self.request_lsp(
 7964                    buffer.clone(),
 7965                    LanguageServerToQuery::Other(server_id),
 7966                    request.clone(),
 7967                    cx,
 7968                );
 7969                async move { (server_id, task.await) }
 7970            })
 7971            .collect::<FuturesUnordered<_>>();
 7972
 7973        cx.background_spawn(async move {
 7974            let mut responses = Vec::with_capacity(response_results.len());
 7975            while let Some((server_id, response_result)) = response_results.next().await {
 7976                if let Some(response) = response_result.log_err() {
 7977                    responses.push((server_id, response));
 7978                }
 7979            }
 7980            responses
 7981        })
 7982    }
 7983
 7984    async fn handle_lsp_command<T: LspCommand>(
 7985        this: Entity<Self>,
 7986        envelope: TypedEnvelope<T::ProtoRequest>,
 7987        mut cx: AsyncApp,
 7988    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 7989    where
 7990        <T::LspRequest as lsp::request::Request>::Params: Send,
 7991        <T::LspRequest as lsp::request::Request>::Result: Send,
 7992    {
 7993        let sender_id = envelope.original_sender_id().unwrap_or_default();
 7994        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 7995        let buffer_handle = this.update(&mut cx, |this, cx| {
 7996            this.buffer_store.read(cx).get_existing(buffer_id)
 7997        })??;
 7998        let request = T::from_proto(
 7999            envelope.payload,
 8000            this.clone(),
 8001            buffer_handle.clone(),
 8002            cx.clone(),
 8003        )
 8004        .await?;
 8005        let response = this
 8006            .update(&mut cx, |this, cx| {
 8007                this.request_lsp(
 8008                    buffer_handle.clone(),
 8009                    LanguageServerToQuery::FirstCapable,
 8010                    request,
 8011                    cx,
 8012                )
 8013            })?
 8014            .await?;
 8015        this.update(&mut cx, |this, cx| {
 8016            Ok(T::response_to_proto(
 8017                response,
 8018                this,
 8019                sender_id,
 8020                &buffer_handle.read(cx).version(),
 8021                cx,
 8022            ))
 8023        })?
 8024    }
 8025
 8026    async fn handle_lsp_query(
 8027        lsp_store: Entity<Self>,
 8028        envelope: TypedEnvelope<proto::LspQuery>,
 8029        mut cx: AsyncApp,
 8030    ) -> Result<proto::Ack> {
 8031        use proto::lsp_query::Request;
 8032        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8033        let lsp_query = envelope.payload;
 8034        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8035        match lsp_query.request.context("invalid LSP query request")? {
 8036            Request::GetReferences(get_references) => {
 8037                let position = get_references.position.clone().and_then(deserialize_anchor);
 8038                Self::query_lsp_locally::<GetReferences>(
 8039                    lsp_store,
 8040                    sender_id,
 8041                    lsp_request_id,
 8042                    get_references,
 8043                    position,
 8044                    cx.clone(),
 8045                )
 8046                .await?;
 8047            }
 8048            Request::GetDocumentColor(get_document_color) => {
 8049                Self::query_lsp_locally::<GetDocumentColor>(
 8050                    lsp_store,
 8051                    sender_id,
 8052                    lsp_request_id,
 8053                    get_document_color,
 8054                    None,
 8055                    cx.clone(),
 8056                )
 8057                .await?;
 8058            }
 8059            Request::GetHover(get_hover) => {
 8060                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8061                Self::query_lsp_locally::<GetHover>(
 8062                    lsp_store,
 8063                    sender_id,
 8064                    lsp_request_id,
 8065                    get_hover,
 8066                    position,
 8067                    cx.clone(),
 8068                )
 8069                .await?;
 8070            }
 8071            Request::GetCodeActions(get_code_actions) => {
 8072                Self::query_lsp_locally::<GetCodeActions>(
 8073                    lsp_store,
 8074                    sender_id,
 8075                    lsp_request_id,
 8076                    get_code_actions,
 8077                    None,
 8078                    cx.clone(),
 8079                )
 8080                .await?;
 8081            }
 8082            Request::GetSignatureHelp(get_signature_help) => {
 8083                let position = get_signature_help
 8084                    .position
 8085                    .clone()
 8086                    .and_then(deserialize_anchor);
 8087                Self::query_lsp_locally::<GetSignatureHelp>(
 8088                    lsp_store,
 8089                    sender_id,
 8090                    lsp_request_id,
 8091                    get_signature_help,
 8092                    position,
 8093                    cx.clone(),
 8094                )
 8095                .await?;
 8096            }
 8097            Request::GetCodeLens(get_code_lens) => {
 8098                Self::query_lsp_locally::<GetCodeLens>(
 8099                    lsp_store,
 8100                    sender_id,
 8101                    lsp_request_id,
 8102                    get_code_lens,
 8103                    None,
 8104                    cx.clone(),
 8105                )
 8106                .await?;
 8107            }
 8108            Request::GetDefinition(get_definition) => {
 8109                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8110                Self::query_lsp_locally::<GetDefinitions>(
 8111                    lsp_store,
 8112                    sender_id,
 8113                    lsp_request_id,
 8114                    get_definition,
 8115                    position,
 8116                    cx.clone(),
 8117                )
 8118                .await?;
 8119            }
 8120            Request::GetDeclaration(get_declaration) => {
 8121                let position = get_declaration
 8122                    .position
 8123                    .clone()
 8124                    .and_then(deserialize_anchor);
 8125                Self::query_lsp_locally::<GetDeclarations>(
 8126                    lsp_store,
 8127                    sender_id,
 8128                    lsp_request_id,
 8129                    get_declaration,
 8130                    position,
 8131                    cx.clone(),
 8132                )
 8133                .await?;
 8134            }
 8135            Request::GetTypeDefinition(get_type_definition) => {
 8136                let position = get_type_definition
 8137                    .position
 8138                    .clone()
 8139                    .and_then(deserialize_anchor);
 8140                Self::query_lsp_locally::<GetTypeDefinitions>(
 8141                    lsp_store,
 8142                    sender_id,
 8143                    lsp_request_id,
 8144                    get_type_definition,
 8145                    position,
 8146                    cx.clone(),
 8147                )
 8148                .await?;
 8149            }
 8150            Request::GetImplementation(get_implementation) => {
 8151                let position = get_implementation
 8152                    .position
 8153                    .clone()
 8154                    .and_then(deserialize_anchor);
 8155                Self::query_lsp_locally::<GetImplementations>(
 8156                    lsp_store,
 8157                    sender_id,
 8158                    lsp_request_id,
 8159                    get_implementation,
 8160                    position,
 8161                    cx.clone(),
 8162                )
 8163                .await?;
 8164            }
 8165            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8166            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8167                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8168                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8169                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8170                    this.buffer_store.read(cx).get_existing(buffer_id)
 8171                })??;
 8172                buffer
 8173                    .update(&mut cx, |buffer, _| {
 8174                        buffer.wait_for_version(version.clone())
 8175                    })?
 8176                    .await?;
 8177                lsp_store.update(&mut cx, |lsp_store, cx| {
 8178                    let existing_queries = lsp_store
 8179                        .running_lsp_requests
 8180                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8181                        .or_default();
 8182                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8183                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8184                    {
 8185                        existing_queries.1.clear();
 8186                    }
 8187                    existing_queries.1.insert(
 8188                        lsp_request_id,
 8189                        cx.spawn(async move |lsp_store, cx| {
 8190                            let diagnostics_pull = lsp_store
 8191                                .update(cx, |lsp_store, cx| {
 8192                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8193                                })
 8194                                .ok();
 8195                            if let Some(diagnostics_pull) = diagnostics_pull {
 8196                                match diagnostics_pull.await {
 8197                                    Ok(()) => {}
 8198                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8199                                };
 8200                            }
 8201                        }),
 8202                    );
 8203                })?;
 8204            }
 8205        }
 8206        Ok(proto::Ack {})
 8207    }
 8208
 8209    async fn handle_lsp_query_response(
 8210        lsp_store: Entity<Self>,
 8211        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8212        cx: AsyncApp,
 8213    ) -> Result<()> {
 8214        lsp_store.read_with(&cx, |lsp_store, _| {
 8215            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8216                upstream_client.handle_lsp_response(envelope.clone());
 8217            }
 8218        })?;
 8219        Ok(())
 8220    }
 8221
 8222    // todo(lsp) remove after Zed Stable hits v0.204.x
 8223    async fn handle_multi_lsp_query(
 8224        lsp_store: Entity<Self>,
 8225        envelope: TypedEnvelope<proto::MultiLspQuery>,
 8226        mut cx: AsyncApp,
 8227    ) -> Result<proto::MultiLspQueryResponse> {
 8228        let response_from_ssh = lsp_store.read_with(&cx, |this, _| {
 8229            let (upstream_client, project_id) = this.upstream_client()?;
 8230            let mut payload = envelope.payload.clone();
 8231            payload.project_id = project_id;
 8232
 8233            Some(upstream_client.request(payload))
 8234        })?;
 8235        if let Some(response_from_ssh) = response_from_ssh {
 8236            return response_from_ssh.await;
 8237        }
 8238
 8239        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8240        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8241        let version = deserialize_version(&envelope.payload.version);
 8242        let buffer = lsp_store.update(&mut cx, |this, cx| {
 8243            this.buffer_store.read(cx).get_existing(buffer_id)
 8244        })??;
 8245        buffer
 8246            .update(&mut cx, |buffer, _| {
 8247                buffer.wait_for_version(version.clone())
 8248            })?
 8249            .await?;
 8250        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
 8251        match envelope
 8252            .payload
 8253            .strategy
 8254            .context("invalid request without the strategy")?
 8255        {
 8256            proto::multi_lsp_query::Strategy::All(_) => {
 8257                // currently, there's only one multiple language servers query strategy,
 8258                // so just ensure it's specified correctly
 8259            }
 8260        }
 8261        match envelope.payload.request {
 8262            Some(proto::multi_lsp_query::Request::GetHover(message)) => {
 8263                buffer
 8264                    .update(&mut cx, |buffer, _| {
 8265                        buffer.wait_for_version(deserialize_version(&message.version))
 8266                    })?
 8267                    .await?;
 8268                let get_hover =
 8269                    GetHover::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8270                        .await?;
 8271                let all_hovers = lsp_store
 8272                    .update(&mut cx, |this, cx| {
 8273                        this.request_multiple_lsp_locally(
 8274                            &buffer,
 8275                            Some(get_hover.position),
 8276                            get_hover,
 8277                            cx,
 8278                        )
 8279                    })?
 8280                    .await
 8281                    .into_iter()
 8282                    .filter_map(|(server_id, hover)| {
 8283                        Some((server_id, remove_empty_hover_blocks(hover?)?))
 8284                    });
 8285                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8286                    responses: all_hovers
 8287                        .map(|(server_id, hover)| proto::LspResponse {
 8288                            server_id: server_id.to_proto(),
 8289                            response: Some(proto::lsp_response::Response::GetHoverResponse(
 8290                                GetHover::response_to_proto(
 8291                                    Some(hover),
 8292                                    project,
 8293                                    sender_id,
 8294                                    &buffer_version,
 8295                                    cx,
 8296                                ),
 8297                            )),
 8298                        })
 8299                        .collect(),
 8300                })
 8301            }
 8302            Some(proto::multi_lsp_query::Request::GetCodeActions(message)) => {
 8303                buffer
 8304                    .update(&mut cx, |buffer, _| {
 8305                        buffer.wait_for_version(deserialize_version(&message.version))
 8306                    })?
 8307                    .await?;
 8308                let get_code_actions = GetCodeActions::from_proto(
 8309                    message,
 8310                    lsp_store.clone(),
 8311                    buffer.clone(),
 8312                    cx.clone(),
 8313                )
 8314                .await?;
 8315
 8316                let all_actions = lsp_store
 8317                    .update(&mut cx, |project, cx| {
 8318                        project.request_multiple_lsp_locally(
 8319                            &buffer,
 8320                            Some(get_code_actions.range.start),
 8321                            get_code_actions,
 8322                            cx,
 8323                        )
 8324                    })?
 8325                    .await
 8326                    .into_iter();
 8327
 8328                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8329                    responses: all_actions
 8330                        .map(|(server_id, code_actions)| proto::LspResponse {
 8331                            server_id: server_id.to_proto(),
 8332                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
 8333                                GetCodeActions::response_to_proto(
 8334                                    code_actions,
 8335                                    project,
 8336                                    sender_id,
 8337                                    &buffer_version,
 8338                                    cx,
 8339                                ),
 8340                            )),
 8341                        })
 8342                        .collect(),
 8343                })
 8344            }
 8345            Some(proto::multi_lsp_query::Request::GetSignatureHelp(message)) => {
 8346                buffer
 8347                    .update(&mut cx, |buffer, _| {
 8348                        buffer.wait_for_version(deserialize_version(&message.version))
 8349                    })?
 8350                    .await?;
 8351                let get_signature_help = GetSignatureHelp::from_proto(
 8352                    message,
 8353                    lsp_store.clone(),
 8354                    buffer.clone(),
 8355                    cx.clone(),
 8356                )
 8357                .await?;
 8358
 8359                let all_signatures = lsp_store
 8360                    .update(&mut cx, |project, cx| {
 8361                        project.request_multiple_lsp_locally(
 8362                            &buffer,
 8363                            Some(get_signature_help.position),
 8364                            get_signature_help,
 8365                            cx,
 8366                        )
 8367                    })?
 8368                    .await
 8369                    .into_iter();
 8370
 8371                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8372                    responses: all_signatures
 8373                        .map(|(server_id, signature_help)| proto::LspResponse {
 8374                            server_id: server_id.to_proto(),
 8375                            response: Some(
 8376                                proto::lsp_response::Response::GetSignatureHelpResponse(
 8377                                    GetSignatureHelp::response_to_proto(
 8378                                        signature_help,
 8379                                        project,
 8380                                        sender_id,
 8381                                        &buffer_version,
 8382                                        cx,
 8383                                    ),
 8384                                ),
 8385                            ),
 8386                        })
 8387                        .collect(),
 8388                })
 8389            }
 8390            Some(proto::multi_lsp_query::Request::GetCodeLens(message)) => {
 8391                buffer
 8392                    .update(&mut cx, |buffer, _| {
 8393                        buffer.wait_for_version(deserialize_version(&message.version))
 8394                    })?
 8395                    .await?;
 8396                let get_code_lens =
 8397                    GetCodeLens::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8398                        .await?;
 8399
 8400                let code_lens_actions = lsp_store
 8401                    .update(&mut cx, |project, cx| {
 8402                        project.request_multiple_lsp_locally(
 8403                            &buffer,
 8404                            None::<usize>,
 8405                            get_code_lens,
 8406                            cx,
 8407                        )
 8408                    })?
 8409                    .await
 8410                    .into_iter();
 8411
 8412                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8413                    responses: code_lens_actions
 8414                        .map(|(server_id, actions)| proto::LspResponse {
 8415                            server_id: server_id.to_proto(),
 8416                            response: Some(proto::lsp_response::Response::GetCodeLensResponse(
 8417                                GetCodeLens::response_to_proto(
 8418                                    actions,
 8419                                    project,
 8420                                    sender_id,
 8421                                    &buffer_version,
 8422                                    cx,
 8423                                ),
 8424                            )),
 8425                        })
 8426                        .collect(),
 8427                })
 8428            }
 8429            Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(message)) => {
 8430                buffer
 8431                    .update(&mut cx, |buffer, _| {
 8432                        buffer.wait_for_version(deserialize_version(&message.version))
 8433                    })?
 8434                    .await?;
 8435                lsp_store
 8436                    .update(&mut cx, |lsp_store, cx| {
 8437                        lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8438                    })?
 8439                    .await?;
 8440                // `pull_diagnostics_for_buffer` will merge in the new diagnostics and send them to the client.
 8441                // The client cannot merge anything into its non-local LspStore, so we do not need to return anything.
 8442                Ok(proto::MultiLspQueryResponse {
 8443                    responses: Vec::new(),
 8444                })
 8445            }
 8446            Some(proto::multi_lsp_query::Request::GetDocumentColor(message)) => {
 8447                buffer
 8448                    .update(&mut cx, |buffer, _| {
 8449                        buffer.wait_for_version(deserialize_version(&message.version))
 8450                    })?
 8451                    .await?;
 8452                let get_document_color = GetDocumentColor::from_proto(
 8453                    message,
 8454                    lsp_store.clone(),
 8455                    buffer.clone(),
 8456                    cx.clone(),
 8457                )
 8458                .await?;
 8459
 8460                let all_colors = lsp_store
 8461                    .update(&mut cx, |project, cx| {
 8462                        project.request_multiple_lsp_locally(
 8463                            &buffer,
 8464                            None::<usize>,
 8465                            get_document_color,
 8466                            cx,
 8467                        )
 8468                    })?
 8469                    .await
 8470                    .into_iter();
 8471
 8472                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8473                    responses: all_colors
 8474                        .map(|(server_id, colors)| proto::LspResponse {
 8475                            server_id: server_id.to_proto(),
 8476                            response: Some(
 8477                                proto::lsp_response::Response::GetDocumentColorResponse(
 8478                                    GetDocumentColor::response_to_proto(
 8479                                        colors,
 8480                                        project,
 8481                                        sender_id,
 8482                                        &buffer_version,
 8483                                        cx,
 8484                                    ),
 8485                                ),
 8486                            ),
 8487                        })
 8488                        .collect(),
 8489                })
 8490            }
 8491            Some(proto::multi_lsp_query::Request::GetDefinition(message)) => {
 8492                let get_definitions = GetDefinitions::from_proto(
 8493                    message,
 8494                    lsp_store.clone(),
 8495                    buffer.clone(),
 8496                    cx.clone(),
 8497                )
 8498                .await?;
 8499
 8500                let definitions = lsp_store
 8501                    .update(&mut cx, |project, cx| {
 8502                        project.request_multiple_lsp_locally(
 8503                            &buffer,
 8504                            Some(get_definitions.position),
 8505                            get_definitions,
 8506                            cx,
 8507                        )
 8508                    })?
 8509                    .await
 8510                    .into_iter();
 8511
 8512                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8513                    responses: definitions
 8514                        .map(|(server_id, definitions)| proto::LspResponse {
 8515                            server_id: server_id.to_proto(),
 8516                            response: Some(proto::lsp_response::Response::GetDefinitionResponse(
 8517                                GetDefinitions::response_to_proto(
 8518                                    definitions,
 8519                                    project,
 8520                                    sender_id,
 8521                                    &buffer_version,
 8522                                    cx,
 8523                                ),
 8524                            )),
 8525                        })
 8526                        .collect(),
 8527                })
 8528            }
 8529            Some(proto::multi_lsp_query::Request::GetDeclaration(message)) => {
 8530                let get_declarations = GetDeclarations::from_proto(
 8531                    message,
 8532                    lsp_store.clone(),
 8533                    buffer.clone(),
 8534                    cx.clone(),
 8535                )
 8536                .await?;
 8537
 8538                let declarations = lsp_store
 8539                    .update(&mut cx, |project, cx| {
 8540                        project.request_multiple_lsp_locally(
 8541                            &buffer,
 8542                            Some(get_declarations.position),
 8543                            get_declarations,
 8544                            cx,
 8545                        )
 8546                    })?
 8547                    .await
 8548                    .into_iter();
 8549
 8550                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8551                    responses: declarations
 8552                        .map(|(server_id, declarations)| proto::LspResponse {
 8553                            server_id: server_id.to_proto(),
 8554                            response: Some(proto::lsp_response::Response::GetDeclarationResponse(
 8555                                GetDeclarations::response_to_proto(
 8556                                    declarations,
 8557                                    project,
 8558                                    sender_id,
 8559                                    &buffer_version,
 8560                                    cx,
 8561                                ),
 8562                            )),
 8563                        })
 8564                        .collect(),
 8565                })
 8566            }
 8567            Some(proto::multi_lsp_query::Request::GetTypeDefinition(message)) => {
 8568                let get_type_definitions = GetTypeDefinitions::from_proto(
 8569                    message,
 8570                    lsp_store.clone(),
 8571                    buffer.clone(),
 8572                    cx.clone(),
 8573                )
 8574                .await?;
 8575
 8576                let type_definitions = lsp_store
 8577                    .update(&mut cx, |project, cx| {
 8578                        project.request_multiple_lsp_locally(
 8579                            &buffer,
 8580                            Some(get_type_definitions.position),
 8581                            get_type_definitions,
 8582                            cx,
 8583                        )
 8584                    })?
 8585                    .await
 8586                    .into_iter();
 8587
 8588                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8589                    responses: type_definitions
 8590                        .map(|(server_id, type_definitions)| proto::LspResponse {
 8591                            server_id: server_id.to_proto(),
 8592                            response: Some(
 8593                                proto::lsp_response::Response::GetTypeDefinitionResponse(
 8594                                    GetTypeDefinitions::response_to_proto(
 8595                                        type_definitions,
 8596                                        project,
 8597                                        sender_id,
 8598                                        &buffer_version,
 8599                                        cx,
 8600                                    ),
 8601                                ),
 8602                            ),
 8603                        })
 8604                        .collect(),
 8605                })
 8606            }
 8607            Some(proto::multi_lsp_query::Request::GetImplementation(message)) => {
 8608                let get_implementations = GetImplementations::from_proto(
 8609                    message,
 8610                    lsp_store.clone(),
 8611                    buffer.clone(),
 8612                    cx.clone(),
 8613                )
 8614                .await?;
 8615
 8616                let implementations = lsp_store
 8617                    .update(&mut cx, |project, cx| {
 8618                        project.request_multiple_lsp_locally(
 8619                            &buffer,
 8620                            Some(get_implementations.position),
 8621                            get_implementations,
 8622                            cx,
 8623                        )
 8624                    })?
 8625                    .await
 8626                    .into_iter();
 8627
 8628                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8629                    responses: implementations
 8630                        .map(|(server_id, implementations)| proto::LspResponse {
 8631                            server_id: server_id.to_proto(),
 8632                            response: Some(
 8633                                proto::lsp_response::Response::GetImplementationResponse(
 8634                                    GetImplementations::response_to_proto(
 8635                                        implementations,
 8636                                        project,
 8637                                        sender_id,
 8638                                        &buffer_version,
 8639                                        cx,
 8640                                    ),
 8641                                ),
 8642                            ),
 8643                        })
 8644                        .collect(),
 8645                })
 8646            }
 8647            Some(proto::multi_lsp_query::Request::GetReferences(message)) => {
 8648                let get_references = GetReferences::from_proto(
 8649                    message,
 8650                    lsp_store.clone(),
 8651                    buffer.clone(),
 8652                    cx.clone(),
 8653                )
 8654                .await?;
 8655
 8656                let references = lsp_store
 8657                    .update(&mut cx, |project, cx| {
 8658                        project.request_multiple_lsp_locally(
 8659                            &buffer,
 8660                            Some(get_references.position),
 8661                            get_references,
 8662                            cx,
 8663                        )
 8664                    })?
 8665                    .await
 8666                    .into_iter();
 8667
 8668                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8669                    responses: references
 8670                        .map(|(server_id, references)| proto::LspResponse {
 8671                            server_id: server_id.to_proto(),
 8672                            response: Some(proto::lsp_response::Response::GetReferencesResponse(
 8673                                GetReferences::response_to_proto(
 8674                                    references,
 8675                                    project,
 8676                                    sender_id,
 8677                                    &buffer_version,
 8678                                    cx,
 8679                                ),
 8680                            )),
 8681                        })
 8682                        .collect(),
 8683                })
 8684            }
 8685            None => anyhow::bail!("empty multi lsp query request"),
 8686        }
 8687    }
 8688
 8689    async fn handle_apply_code_action(
 8690        this: Entity<Self>,
 8691        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8692        mut cx: AsyncApp,
 8693    ) -> Result<proto::ApplyCodeActionResponse> {
 8694        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8695        let action =
 8696            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8697        let apply_code_action = this.update(&mut cx, |this, cx| {
 8698            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8699            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8700            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8701        })??;
 8702
 8703        let project_transaction = apply_code_action.await?;
 8704        let project_transaction = this.update(&mut cx, |this, cx| {
 8705            this.buffer_store.update(cx, |buffer_store, cx| {
 8706                buffer_store.serialize_project_transaction_for_peer(
 8707                    project_transaction,
 8708                    sender_id,
 8709                    cx,
 8710                )
 8711            })
 8712        })?;
 8713        Ok(proto::ApplyCodeActionResponse {
 8714            transaction: Some(project_transaction),
 8715        })
 8716    }
 8717
 8718    async fn handle_register_buffer_with_language_servers(
 8719        this: Entity<Self>,
 8720        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8721        mut cx: AsyncApp,
 8722    ) -> Result<proto::Ack> {
 8723        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8724        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8725        this.update(&mut cx, |this, cx| {
 8726            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8727                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8728                    project_id: upstream_project_id,
 8729                    buffer_id: buffer_id.to_proto(),
 8730                    only_servers: envelope.payload.only_servers,
 8731                });
 8732            }
 8733
 8734            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8735                anyhow::bail!("buffer is not open");
 8736            };
 8737
 8738            let handle = this.register_buffer_with_language_servers(
 8739                &buffer,
 8740                envelope
 8741                    .payload
 8742                    .only_servers
 8743                    .into_iter()
 8744                    .filter_map(|selector| {
 8745                        Some(match selector.selector? {
 8746                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8747                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8748                            }
 8749                            proto::language_server_selector::Selector::Name(name) => {
 8750                                LanguageServerSelector::Name(LanguageServerName(
 8751                                    SharedString::from(name),
 8752                                ))
 8753                            }
 8754                        })
 8755                    })
 8756                    .collect(),
 8757                false,
 8758                cx,
 8759            );
 8760            this.buffer_store().update(cx, |buffer_store, _| {
 8761                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8762            });
 8763
 8764            Ok(())
 8765        })??;
 8766        Ok(proto::Ack {})
 8767    }
 8768
 8769    async fn handle_rename_project_entry(
 8770        this: Entity<Self>,
 8771        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8772        mut cx: AsyncApp,
 8773    ) -> Result<proto::ProjectEntryResponse> {
 8774        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8775        let (worktree_id, worktree, old_path, is_dir) = this
 8776            .update(&mut cx, |this, cx| {
 8777                this.worktree_store
 8778                    .read(cx)
 8779                    .worktree_and_entry_for_id(entry_id, cx)
 8780                    .map(|(worktree, entry)| {
 8781                        (
 8782                            worktree.read(cx).id(),
 8783                            worktree,
 8784                            entry.path.clone(),
 8785                            entry.is_dir(),
 8786                        )
 8787                    })
 8788            })?
 8789            .context("worktree not found")?;
 8790        let (old_abs_path, new_abs_path) = {
 8791            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8792            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8793            (root_path.join(&old_path), root_path.join(&new_path))
 8794        };
 8795
 8796        let _transaction = Self::will_rename_entry(
 8797            this.downgrade(),
 8798            worktree_id,
 8799            &old_abs_path,
 8800            &new_abs_path,
 8801            is_dir,
 8802            cx.clone(),
 8803        )
 8804        .await;
 8805        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8806        this.read_with(&cx, |this, _| {
 8807            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8808        })
 8809        .ok();
 8810        response
 8811    }
 8812
 8813    async fn handle_update_diagnostic_summary(
 8814        this: Entity<Self>,
 8815        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8816        mut cx: AsyncApp,
 8817    ) -> Result<()> {
 8818        this.update(&mut cx, |lsp_store, cx| {
 8819            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8820            let mut updated_diagnostics_paths = HashMap::default();
 8821            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8822            for message_summary in envelope
 8823                .payload
 8824                .summary
 8825                .into_iter()
 8826                .chain(envelope.payload.more_summaries)
 8827            {
 8828                let project_path = ProjectPath {
 8829                    worktree_id,
 8830                    path: Arc::<Path>::from_proto(message_summary.path),
 8831                };
 8832                let path = project_path.path.clone();
 8833                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8834                let summary = DiagnosticSummary {
 8835                    error_count: message_summary.error_count as usize,
 8836                    warning_count: message_summary.warning_count as usize,
 8837                };
 8838
 8839                if summary.is_empty() {
 8840                    if let Some(worktree_summaries) =
 8841                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8842                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8843                    {
 8844                        summaries.remove(&server_id);
 8845                        if summaries.is_empty() {
 8846                            worktree_summaries.remove(&path);
 8847                        }
 8848                    }
 8849                } else {
 8850                    lsp_store
 8851                        .diagnostic_summaries
 8852                        .entry(worktree_id)
 8853                        .or_default()
 8854                        .entry(path)
 8855                        .or_default()
 8856                        .insert(server_id, summary);
 8857                }
 8858
 8859                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8860                    match &mut diagnostics_summary {
 8861                        Some(diagnostics_summary) => {
 8862                            diagnostics_summary
 8863                                .more_summaries
 8864                                .push(proto::DiagnosticSummary {
 8865                                    path: project_path.path.as_ref().to_proto(),
 8866                                    language_server_id: server_id.0 as u64,
 8867                                    error_count: summary.error_count as u32,
 8868                                    warning_count: summary.warning_count as u32,
 8869                                })
 8870                        }
 8871                        None => {
 8872                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8873                                project_id: *project_id,
 8874                                worktree_id: worktree_id.to_proto(),
 8875                                summary: Some(proto::DiagnosticSummary {
 8876                                    path: project_path.path.as_ref().to_proto(),
 8877                                    language_server_id: server_id.0 as u64,
 8878                                    error_count: summary.error_count as u32,
 8879                                    warning_count: summary.warning_count as u32,
 8880                                }),
 8881                                more_summaries: Vec::new(),
 8882                            })
 8883                        }
 8884                    }
 8885                }
 8886                updated_diagnostics_paths
 8887                    .entry(server_id)
 8888                    .or_insert_with(Vec::new)
 8889                    .push(project_path);
 8890            }
 8891
 8892            if let Some((diagnostics_summary, (downstream_client, _))) =
 8893                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8894            {
 8895                downstream_client.send(diagnostics_summary).log_err();
 8896            }
 8897            for (server_id, paths) in updated_diagnostics_paths {
 8898                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8899            }
 8900            Ok(())
 8901        })?
 8902    }
 8903
 8904    async fn handle_start_language_server(
 8905        lsp_store: Entity<Self>,
 8906        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8907        mut cx: AsyncApp,
 8908    ) -> Result<()> {
 8909        let server = envelope.payload.server.context("invalid server")?;
 8910        let server_capabilities =
 8911            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8912                .with_context(|| {
 8913                    format!(
 8914                        "incorrect server capabilities {}",
 8915                        envelope.payload.capabilities
 8916                    )
 8917                })?;
 8918        lsp_store.update(&mut cx, |lsp_store, cx| {
 8919            let server_id = LanguageServerId(server.id as usize);
 8920            let server_name = LanguageServerName::from_proto(server.name.clone());
 8921            lsp_store
 8922                .lsp_server_capabilities
 8923                .insert(server_id, server_capabilities);
 8924            lsp_store.language_server_statuses.insert(
 8925                server_id,
 8926                LanguageServerStatus {
 8927                    name: server_name.clone(),
 8928                    pending_work: Default::default(),
 8929                    has_pending_diagnostic_updates: false,
 8930                    progress_tokens: Default::default(),
 8931                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8932                },
 8933            );
 8934            cx.emit(LspStoreEvent::LanguageServerAdded(
 8935                server_id,
 8936                server_name,
 8937                server.worktree_id.map(WorktreeId::from_proto),
 8938            ));
 8939            cx.notify();
 8940        })?;
 8941        Ok(())
 8942    }
 8943
 8944    async fn handle_update_language_server(
 8945        lsp_store: Entity<Self>,
 8946        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8947        mut cx: AsyncApp,
 8948    ) -> Result<()> {
 8949        lsp_store.update(&mut cx, |lsp_store, cx| {
 8950            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8951
 8952            match envelope.payload.variant.context("invalid variant")? {
 8953                proto::update_language_server::Variant::WorkStart(payload) => {
 8954                    lsp_store.on_lsp_work_start(
 8955                        language_server_id,
 8956                        payload.token,
 8957                        LanguageServerProgress {
 8958                            title: payload.title,
 8959                            is_disk_based_diagnostics_progress: false,
 8960                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8961                            message: payload.message,
 8962                            percentage: payload.percentage.map(|p| p as usize),
 8963                            last_update_at: cx.background_executor().now(),
 8964                        },
 8965                        cx,
 8966                    );
 8967                }
 8968                proto::update_language_server::Variant::WorkProgress(payload) => {
 8969                    lsp_store.on_lsp_work_progress(
 8970                        language_server_id,
 8971                        payload.token,
 8972                        LanguageServerProgress {
 8973                            title: None,
 8974                            is_disk_based_diagnostics_progress: false,
 8975                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8976                            message: payload.message,
 8977                            percentage: payload.percentage.map(|p| p as usize),
 8978                            last_update_at: cx.background_executor().now(),
 8979                        },
 8980                        cx,
 8981                    );
 8982                }
 8983
 8984                proto::update_language_server::Variant::WorkEnd(payload) => {
 8985                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8986                }
 8987
 8988                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8989                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8990                }
 8991
 8992                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8993                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8994                }
 8995
 8996                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8997                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8998                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8999                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9000                        language_server_id,
 9001                        name: envelope
 9002                            .payload
 9003                            .server_name
 9004                            .map(SharedString::new)
 9005                            .map(LanguageServerName),
 9006                        message: non_lsp,
 9007                    });
 9008                }
 9009            }
 9010
 9011            Ok(())
 9012        })?
 9013    }
 9014
 9015    async fn handle_language_server_log(
 9016        this: Entity<Self>,
 9017        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9018        mut cx: AsyncApp,
 9019    ) -> Result<()> {
 9020        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9021        let log_type = envelope
 9022            .payload
 9023            .log_type
 9024            .map(LanguageServerLogType::from_proto)
 9025            .context("invalid language server log type")?;
 9026
 9027        let message = envelope.payload.message;
 9028
 9029        this.update(&mut cx, |_, cx| {
 9030            cx.emit(LspStoreEvent::LanguageServerLog(
 9031                language_server_id,
 9032                log_type,
 9033                message,
 9034            ));
 9035        })
 9036    }
 9037
 9038    async fn handle_lsp_ext_cancel_flycheck(
 9039        lsp_store: Entity<Self>,
 9040        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9041        cx: AsyncApp,
 9042    ) -> Result<proto::Ack> {
 9043        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9044        lsp_store.read_with(&cx, |lsp_store, _| {
 9045            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9046                server
 9047                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 9048                    .context("handling lsp ext cancel flycheck")
 9049            } else {
 9050                anyhow::Ok(())
 9051            }
 9052        })??;
 9053
 9054        Ok(proto::Ack {})
 9055    }
 9056
 9057    async fn handle_lsp_ext_run_flycheck(
 9058        lsp_store: Entity<Self>,
 9059        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9060        mut cx: AsyncApp,
 9061    ) -> Result<proto::Ack> {
 9062        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9063        lsp_store.update(&mut cx, |lsp_store, cx| {
 9064            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9065                let text_document = if envelope.payload.current_file_only {
 9066                    let buffer_id = envelope
 9067                        .payload
 9068                        .buffer_id
 9069                        .map(|id| BufferId::new(id))
 9070                        .transpose()?;
 9071                    buffer_id
 9072                        .and_then(|buffer_id| {
 9073                            lsp_store
 9074                                .buffer_store()
 9075                                .read(cx)
 9076                                .get(buffer_id)
 9077                                .and_then(|buffer| {
 9078                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9079                                })
 9080                                .map(|path| make_text_document_identifier(&path))
 9081                        })
 9082                        .transpose()?
 9083                } else {
 9084                    None
 9085                };
 9086                server
 9087                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9088                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9089                    )
 9090                    .context("handling lsp ext run flycheck")
 9091            } else {
 9092                anyhow::Ok(())
 9093            }
 9094        })??;
 9095
 9096        Ok(proto::Ack {})
 9097    }
 9098
 9099    async fn handle_lsp_ext_clear_flycheck(
 9100        lsp_store: Entity<Self>,
 9101        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9102        cx: AsyncApp,
 9103    ) -> Result<proto::Ack> {
 9104        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9105        lsp_store.read_with(&cx, |lsp_store, _| {
 9106            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9107                server
 9108                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 9109                    .context("handling lsp ext clear flycheck")
 9110            } else {
 9111                anyhow::Ok(())
 9112            }
 9113        })??;
 9114
 9115        Ok(proto::Ack {})
 9116    }
 9117
 9118    pub fn disk_based_diagnostics_started(
 9119        &mut self,
 9120        language_server_id: LanguageServerId,
 9121        cx: &mut Context<Self>,
 9122    ) {
 9123        if let Some(language_server_status) =
 9124            self.language_server_statuses.get_mut(&language_server_id)
 9125        {
 9126            language_server_status.has_pending_diagnostic_updates = true;
 9127        }
 9128
 9129        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9130        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9131            language_server_id,
 9132            name: self
 9133                .language_server_adapter_for_id(language_server_id)
 9134                .map(|adapter| adapter.name()),
 9135            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9136                Default::default(),
 9137            ),
 9138        })
 9139    }
 9140
 9141    pub fn disk_based_diagnostics_finished(
 9142        &mut self,
 9143        language_server_id: LanguageServerId,
 9144        cx: &mut Context<Self>,
 9145    ) {
 9146        if let Some(language_server_status) =
 9147            self.language_server_statuses.get_mut(&language_server_id)
 9148        {
 9149            language_server_status.has_pending_diagnostic_updates = false;
 9150        }
 9151
 9152        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9153        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9154            language_server_id,
 9155            name: self
 9156                .language_server_adapter_for_id(language_server_id)
 9157                .map(|adapter| adapter.name()),
 9158            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9159                Default::default(),
 9160            ),
 9161        })
 9162    }
 9163
 9164    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9165    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9166    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9167    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9168    // the language server might take some time to publish diagnostics.
 9169    fn simulate_disk_based_diagnostics_events_if_needed(
 9170        &mut self,
 9171        language_server_id: LanguageServerId,
 9172        cx: &mut Context<Self>,
 9173    ) {
 9174        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9175
 9176        let Some(LanguageServerState::Running {
 9177            simulate_disk_based_diagnostics_completion,
 9178            adapter,
 9179            ..
 9180        }) = self
 9181            .as_local_mut()
 9182            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9183        else {
 9184            return;
 9185        };
 9186
 9187        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9188            return;
 9189        }
 9190
 9191        let prev_task =
 9192            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9193                cx.background_executor()
 9194                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9195                    .await;
 9196
 9197                this.update(cx, |this, cx| {
 9198                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9199
 9200                    if let Some(LanguageServerState::Running {
 9201                        simulate_disk_based_diagnostics_completion,
 9202                        ..
 9203                    }) = this.as_local_mut().and_then(|local_store| {
 9204                        local_store.language_servers.get_mut(&language_server_id)
 9205                    }) {
 9206                        *simulate_disk_based_diagnostics_completion = None;
 9207                    }
 9208                })
 9209                .ok();
 9210            }));
 9211
 9212        if prev_task.is_none() {
 9213            self.disk_based_diagnostics_started(language_server_id, cx);
 9214        }
 9215    }
 9216
 9217    pub fn language_server_statuses(
 9218        &self,
 9219    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9220        self.language_server_statuses
 9221            .iter()
 9222            .map(|(key, value)| (*key, value))
 9223    }
 9224
 9225    pub(super) fn did_rename_entry(
 9226        &self,
 9227        worktree_id: WorktreeId,
 9228        old_path: &Path,
 9229        new_path: &Path,
 9230        is_dir: bool,
 9231    ) {
 9232        maybe!({
 9233            let local_store = self.as_local()?;
 9234
 9235            let old_uri = lsp::Uri::from_file_path(old_path)
 9236                .ok()
 9237                .map(|uri| uri.to_string())?;
 9238            let new_uri = lsp::Uri::from_file_path(new_path)
 9239                .ok()
 9240                .map(|uri| uri.to_string())?;
 9241
 9242            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9243                let Some(filter) = local_store
 9244                    .language_server_paths_watched_for_rename
 9245                    .get(&language_server.server_id())
 9246                else {
 9247                    continue;
 9248                };
 9249
 9250                if filter.should_send_did_rename(&old_uri, is_dir) {
 9251                    language_server
 9252                        .notify::<DidRenameFiles>(&RenameFilesParams {
 9253                            files: vec![FileRename {
 9254                                old_uri: old_uri.clone(),
 9255                                new_uri: new_uri.clone(),
 9256                            }],
 9257                        })
 9258                        .ok();
 9259                }
 9260            }
 9261            Some(())
 9262        });
 9263    }
 9264
 9265    pub(super) fn will_rename_entry(
 9266        this: WeakEntity<Self>,
 9267        worktree_id: WorktreeId,
 9268        old_path: &Path,
 9269        new_path: &Path,
 9270        is_dir: bool,
 9271        cx: AsyncApp,
 9272    ) -> Task<ProjectTransaction> {
 9273        let old_uri = lsp::Uri::from_file_path(old_path)
 9274            .ok()
 9275            .map(|uri| uri.to_string());
 9276        let new_uri = lsp::Uri::from_file_path(new_path)
 9277            .ok()
 9278            .map(|uri| uri.to_string());
 9279        cx.spawn(async move |cx| {
 9280            let mut tasks = vec![];
 9281            this.update(cx, |this, cx| {
 9282                let local_store = this.as_local()?;
 9283                let old_uri = old_uri?;
 9284                let new_uri = new_uri?;
 9285                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9286                    let Some(filter) = local_store
 9287                        .language_server_paths_watched_for_rename
 9288                        .get(&language_server.server_id())
 9289                    else {
 9290                        continue;
 9291                    };
 9292
 9293                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9294                        let apply_edit = cx.spawn({
 9295                            let old_uri = old_uri.clone();
 9296                            let new_uri = new_uri.clone();
 9297                            let language_server = language_server.clone();
 9298                            async move |this, cx| {
 9299                                let edit = language_server
 9300                                    .request::<WillRenameFiles>(RenameFilesParams {
 9301                                        files: vec![FileRename { old_uri, new_uri }],
 9302                                    })
 9303                                    .await
 9304                                    .into_response()
 9305                                    .context("will rename files")
 9306                                    .log_err()
 9307                                    .flatten()?;
 9308
 9309                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9310                                    this.upgrade()?,
 9311                                    edit,
 9312                                    false,
 9313                                    language_server.clone(),
 9314                                    cx,
 9315                                )
 9316                                .await
 9317                                .ok()?;
 9318                                Some(transaction)
 9319                            }
 9320                        });
 9321                        tasks.push(apply_edit);
 9322                    }
 9323                }
 9324                Some(())
 9325            })
 9326            .ok()
 9327            .flatten();
 9328            let mut merged_transaction = ProjectTransaction::default();
 9329            for task in tasks {
 9330                // Await on tasks sequentially so that the order of application of edits is deterministic
 9331                // (at least with regards to the order of registration of language servers)
 9332                if let Some(transaction) = task.await {
 9333                    for (buffer, buffer_transaction) in transaction.0 {
 9334                        merged_transaction.0.insert(buffer, buffer_transaction);
 9335                    }
 9336                }
 9337            }
 9338            merged_transaction
 9339        })
 9340    }
 9341
 9342    fn lsp_notify_abs_paths_changed(
 9343        &mut self,
 9344        server_id: LanguageServerId,
 9345        changes: Vec<PathEvent>,
 9346    ) {
 9347        maybe!({
 9348            let server = self.language_server_for_id(server_id)?;
 9349            let changes = changes
 9350                .into_iter()
 9351                .filter_map(|event| {
 9352                    let typ = match event.kind? {
 9353                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9354                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9355                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9356                    };
 9357                    Some(lsp::FileEvent {
 9358                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9359                        typ,
 9360                    })
 9361                })
 9362                .collect::<Vec<_>>();
 9363            if !changes.is_empty() {
 9364                server
 9365                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9366                        &lsp::DidChangeWatchedFilesParams { changes },
 9367                    )
 9368                    .ok();
 9369            }
 9370            Some(())
 9371        });
 9372    }
 9373
 9374    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9375        self.as_local()?.language_server_for_id(id)
 9376    }
 9377
 9378    fn on_lsp_progress(
 9379        &mut self,
 9380        progress: lsp::ProgressParams,
 9381        language_server_id: LanguageServerId,
 9382        disk_based_diagnostics_progress_token: Option<String>,
 9383        cx: &mut Context<Self>,
 9384    ) {
 9385        let token = match progress.token {
 9386            lsp::NumberOrString::String(token) => token,
 9387            lsp::NumberOrString::Number(token) => {
 9388                log::info!("skipping numeric progress token {}", token);
 9389                return;
 9390            }
 9391        };
 9392
 9393        match progress.value {
 9394            lsp::ProgressParamsValue::WorkDone(progress) => {
 9395                self.handle_work_done_progress(
 9396                    progress,
 9397                    language_server_id,
 9398                    disk_based_diagnostics_progress_token,
 9399                    token,
 9400                    cx,
 9401                );
 9402            }
 9403            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9404                if let Some(LanguageServerState::Running {
 9405                    workspace_refresh_task: Some(workspace_refresh_task),
 9406                    ..
 9407                }) = self
 9408                    .as_local_mut()
 9409                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9410                {
 9411                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9412                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9413                }
 9414            }
 9415        }
 9416    }
 9417
 9418    fn handle_work_done_progress(
 9419        &mut self,
 9420        progress: lsp::WorkDoneProgress,
 9421        language_server_id: LanguageServerId,
 9422        disk_based_diagnostics_progress_token: Option<String>,
 9423        token: String,
 9424        cx: &mut Context<Self>,
 9425    ) {
 9426        let language_server_status =
 9427            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9428                status
 9429            } else {
 9430                return;
 9431            };
 9432
 9433        if !language_server_status.progress_tokens.contains(&token) {
 9434            return;
 9435        }
 9436
 9437        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9438            .as_ref()
 9439            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9440
 9441        match progress {
 9442            lsp::WorkDoneProgress::Begin(report) => {
 9443                if is_disk_based_diagnostics_progress {
 9444                    self.disk_based_diagnostics_started(language_server_id, cx);
 9445                }
 9446                self.on_lsp_work_start(
 9447                    language_server_id,
 9448                    token.clone(),
 9449                    LanguageServerProgress {
 9450                        title: Some(report.title),
 9451                        is_disk_based_diagnostics_progress,
 9452                        is_cancellable: report.cancellable.unwrap_or(false),
 9453                        message: report.message.clone(),
 9454                        percentage: report.percentage.map(|p| p as usize),
 9455                        last_update_at: cx.background_executor().now(),
 9456                    },
 9457                    cx,
 9458                );
 9459            }
 9460            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9461                language_server_id,
 9462                token,
 9463                LanguageServerProgress {
 9464                    title: None,
 9465                    is_disk_based_diagnostics_progress,
 9466                    is_cancellable: report.cancellable.unwrap_or(false),
 9467                    message: report.message,
 9468                    percentage: report.percentage.map(|p| p as usize),
 9469                    last_update_at: cx.background_executor().now(),
 9470                },
 9471                cx,
 9472            ),
 9473            lsp::WorkDoneProgress::End(_) => {
 9474                language_server_status.progress_tokens.remove(&token);
 9475                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9476                if is_disk_based_diagnostics_progress {
 9477                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9478                }
 9479            }
 9480        }
 9481    }
 9482
 9483    fn on_lsp_work_start(
 9484        &mut self,
 9485        language_server_id: LanguageServerId,
 9486        token: String,
 9487        progress: LanguageServerProgress,
 9488        cx: &mut Context<Self>,
 9489    ) {
 9490        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9491            status.pending_work.insert(token.clone(), progress.clone());
 9492            cx.notify();
 9493        }
 9494        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9495            language_server_id,
 9496            name: self
 9497                .language_server_adapter_for_id(language_server_id)
 9498                .map(|adapter| adapter.name()),
 9499            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9500                token,
 9501                title: progress.title,
 9502                message: progress.message,
 9503                percentage: progress.percentage.map(|p| p as u32),
 9504                is_cancellable: Some(progress.is_cancellable),
 9505            }),
 9506        })
 9507    }
 9508
 9509    fn on_lsp_work_progress(
 9510        &mut self,
 9511        language_server_id: LanguageServerId,
 9512        token: String,
 9513        progress: LanguageServerProgress,
 9514        cx: &mut Context<Self>,
 9515    ) {
 9516        let mut did_update = false;
 9517        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9518            match status.pending_work.entry(token.clone()) {
 9519                btree_map::Entry::Vacant(entry) => {
 9520                    entry.insert(progress.clone());
 9521                    did_update = true;
 9522                }
 9523                btree_map::Entry::Occupied(mut entry) => {
 9524                    let entry = entry.get_mut();
 9525                    if (progress.last_update_at - entry.last_update_at)
 9526                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9527                    {
 9528                        entry.last_update_at = progress.last_update_at;
 9529                        if progress.message.is_some() {
 9530                            entry.message = progress.message.clone();
 9531                        }
 9532                        if progress.percentage.is_some() {
 9533                            entry.percentage = progress.percentage;
 9534                        }
 9535                        if progress.is_cancellable != entry.is_cancellable {
 9536                            entry.is_cancellable = progress.is_cancellable;
 9537                        }
 9538                        did_update = true;
 9539                    }
 9540                }
 9541            }
 9542        }
 9543
 9544        if did_update {
 9545            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9546                language_server_id,
 9547                name: self
 9548                    .language_server_adapter_for_id(language_server_id)
 9549                    .map(|adapter| adapter.name()),
 9550                message: proto::update_language_server::Variant::WorkProgress(
 9551                    proto::LspWorkProgress {
 9552                        token,
 9553                        message: progress.message,
 9554                        percentage: progress.percentage.map(|p| p as u32),
 9555                        is_cancellable: Some(progress.is_cancellable),
 9556                    },
 9557                ),
 9558            })
 9559        }
 9560    }
 9561
 9562    fn on_lsp_work_end(
 9563        &mut self,
 9564        language_server_id: LanguageServerId,
 9565        token: String,
 9566        cx: &mut Context<Self>,
 9567    ) {
 9568        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9569            if let Some(work) = status.pending_work.remove(&token)
 9570                && !work.is_disk_based_diagnostics_progress
 9571            {
 9572                cx.emit(LspStoreEvent::RefreshInlayHints);
 9573            }
 9574            cx.notify();
 9575        }
 9576
 9577        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9578            language_server_id,
 9579            name: self
 9580                .language_server_adapter_for_id(language_server_id)
 9581                .map(|adapter| adapter.name()),
 9582            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9583        })
 9584    }
 9585
 9586    pub async fn handle_resolve_completion_documentation(
 9587        this: Entity<Self>,
 9588        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9589        mut cx: AsyncApp,
 9590    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9591        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9592
 9593        let completion = this
 9594            .read_with(&cx, |this, cx| {
 9595                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9596                let server = this
 9597                    .language_server_for_id(id)
 9598                    .with_context(|| format!("No language server {id}"))?;
 9599
 9600                anyhow::Ok(cx.background_spawn(async move {
 9601                    let can_resolve = server
 9602                        .capabilities()
 9603                        .completion_provider
 9604                        .as_ref()
 9605                        .and_then(|options| options.resolve_provider)
 9606                        .unwrap_or(false);
 9607                    if can_resolve {
 9608                        server
 9609                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9610                            .await
 9611                            .into_response()
 9612                            .context("resolve completion item")
 9613                    } else {
 9614                        anyhow::Ok(lsp_completion)
 9615                    }
 9616                }))
 9617            })??
 9618            .await?;
 9619
 9620        let mut documentation_is_markdown = false;
 9621        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9622        let documentation = match completion.documentation {
 9623            Some(lsp::Documentation::String(text)) => text,
 9624
 9625            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9626                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9627                value
 9628            }
 9629
 9630            _ => String::new(),
 9631        };
 9632
 9633        // If we have a new buffer_id, that means we're talking to a new client
 9634        // and want to check for new text_edits in the completion too.
 9635        let mut old_replace_start = None;
 9636        let mut old_replace_end = None;
 9637        let mut old_insert_start = None;
 9638        let mut old_insert_end = None;
 9639        let mut new_text = String::default();
 9640        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9641            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9642                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9643                anyhow::Ok(buffer.read(cx).snapshot())
 9644            })??;
 9645
 9646            if let Some(text_edit) = completion.text_edit.as_ref() {
 9647                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9648
 9649                if let Some(mut edit) = edit {
 9650                    LineEnding::normalize(&mut edit.new_text);
 9651
 9652                    new_text = edit.new_text;
 9653                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9654                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9655                    if let Some(insert_range) = edit.insert_range {
 9656                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9657                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9658                    }
 9659                }
 9660            }
 9661        }
 9662
 9663        Ok(proto::ResolveCompletionDocumentationResponse {
 9664            documentation,
 9665            documentation_is_markdown,
 9666            old_replace_start,
 9667            old_replace_end,
 9668            new_text,
 9669            lsp_completion,
 9670            old_insert_start,
 9671            old_insert_end,
 9672        })
 9673    }
 9674
 9675    async fn handle_on_type_formatting(
 9676        this: Entity<Self>,
 9677        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9678        mut cx: AsyncApp,
 9679    ) -> Result<proto::OnTypeFormattingResponse> {
 9680        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9681            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9682            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9683            let position = envelope
 9684                .payload
 9685                .position
 9686                .and_then(deserialize_anchor)
 9687                .context("invalid position")?;
 9688            anyhow::Ok(this.apply_on_type_formatting(
 9689                buffer,
 9690                position,
 9691                envelope.payload.trigger.clone(),
 9692                cx,
 9693            ))
 9694        })??;
 9695
 9696        let transaction = on_type_formatting
 9697            .await?
 9698            .as_ref()
 9699            .map(language::proto::serialize_transaction);
 9700        Ok(proto::OnTypeFormattingResponse { transaction })
 9701    }
 9702
 9703    async fn handle_refresh_inlay_hints(
 9704        this: Entity<Self>,
 9705        _: TypedEnvelope<proto::RefreshInlayHints>,
 9706        mut cx: AsyncApp,
 9707    ) -> Result<proto::Ack> {
 9708        this.update(&mut cx, |_, cx| {
 9709            cx.emit(LspStoreEvent::RefreshInlayHints);
 9710        })?;
 9711        Ok(proto::Ack {})
 9712    }
 9713
 9714    async fn handle_pull_workspace_diagnostics(
 9715        lsp_store: Entity<Self>,
 9716        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9717        mut cx: AsyncApp,
 9718    ) -> Result<proto::Ack> {
 9719        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9720        lsp_store.update(&mut cx, |lsp_store, _| {
 9721            lsp_store.pull_workspace_diagnostics(server_id);
 9722        })?;
 9723        Ok(proto::Ack {})
 9724    }
 9725
 9726    async fn handle_inlay_hints(
 9727        this: Entity<Self>,
 9728        envelope: TypedEnvelope<proto::InlayHints>,
 9729        mut cx: AsyncApp,
 9730    ) -> Result<proto::InlayHintsResponse> {
 9731        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9732        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9733        let buffer = this.update(&mut cx, |this, cx| {
 9734            this.buffer_store.read(cx).get_existing(buffer_id)
 9735        })??;
 9736        buffer
 9737            .update(&mut cx, |buffer, _| {
 9738                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9739            })?
 9740            .await
 9741            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9742
 9743        let start = envelope
 9744            .payload
 9745            .start
 9746            .and_then(deserialize_anchor)
 9747            .context("missing range start")?;
 9748        let end = envelope
 9749            .payload
 9750            .end
 9751            .and_then(deserialize_anchor)
 9752            .context("missing range end")?;
 9753        let buffer_hints = this
 9754            .update(&mut cx, |lsp_store, cx| {
 9755                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9756            })?
 9757            .await
 9758            .context("inlay hints fetch")?;
 9759
 9760        this.update(&mut cx, |project, cx| {
 9761            InlayHints::response_to_proto(
 9762                buffer_hints,
 9763                project,
 9764                sender_id,
 9765                &buffer.read(cx).version(),
 9766                cx,
 9767            )
 9768        })
 9769    }
 9770
 9771    async fn handle_get_color_presentation(
 9772        lsp_store: Entity<Self>,
 9773        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9774        mut cx: AsyncApp,
 9775    ) -> Result<proto::GetColorPresentationResponse> {
 9776        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9777        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9778            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9779        })??;
 9780
 9781        let color = envelope
 9782            .payload
 9783            .color
 9784            .context("invalid color resolve request")?;
 9785        let start = color
 9786            .lsp_range_start
 9787            .context("invalid color resolve request")?;
 9788        let end = color
 9789            .lsp_range_end
 9790            .context("invalid color resolve request")?;
 9791
 9792        let color = DocumentColor {
 9793            lsp_range: lsp::Range {
 9794                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9795                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9796            },
 9797            color: lsp::Color {
 9798                red: color.red,
 9799                green: color.green,
 9800                blue: color.blue,
 9801                alpha: color.alpha,
 9802            },
 9803            resolved: false,
 9804            color_presentations: Vec::new(),
 9805        };
 9806        let resolved_color = lsp_store
 9807            .update(&mut cx, |lsp_store, cx| {
 9808                lsp_store.resolve_color_presentation(
 9809                    color,
 9810                    buffer.clone(),
 9811                    LanguageServerId(envelope.payload.server_id as usize),
 9812                    cx,
 9813                )
 9814            })?
 9815            .await
 9816            .context("resolving color presentation")?;
 9817
 9818        Ok(proto::GetColorPresentationResponse {
 9819            presentations: resolved_color
 9820                .color_presentations
 9821                .into_iter()
 9822                .map(|presentation| proto::ColorPresentation {
 9823                    label: presentation.label.to_string(),
 9824                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9825                    additional_text_edits: presentation
 9826                        .additional_text_edits
 9827                        .into_iter()
 9828                        .map(serialize_lsp_edit)
 9829                        .collect(),
 9830                })
 9831                .collect(),
 9832        })
 9833    }
 9834
 9835    async fn handle_resolve_inlay_hint(
 9836        this: Entity<Self>,
 9837        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9838        mut cx: AsyncApp,
 9839    ) -> Result<proto::ResolveInlayHintResponse> {
 9840        let proto_hint = envelope
 9841            .payload
 9842            .hint
 9843            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9844        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9845            .context("resolved proto inlay hint conversion")?;
 9846        let buffer = this.update(&mut cx, |this, cx| {
 9847            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9848            this.buffer_store.read(cx).get_existing(buffer_id)
 9849        })??;
 9850        let response_hint = this
 9851            .update(&mut cx, |this, cx| {
 9852                this.resolve_inlay_hint(
 9853                    hint,
 9854                    buffer,
 9855                    LanguageServerId(envelope.payload.language_server_id as usize),
 9856                    cx,
 9857                )
 9858            })?
 9859            .await
 9860            .context("inlay hints fetch")?;
 9861        Ok(proto::ResolveInlayHintResponse {
 9862            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9863        })
 9864    }
 9865
 9866    async fn handle_refresh_code_lens(
 9867        this: Entity<Self>,
 9868        _: TypedEnvelope<proto::RefreshCodeLens>,
 9869        mut cx: AsyncApp,
 9870    ) -> Result<proto::Ack> {
 9871        this.update(&mut cx, |_, cx| {
 9872            cx.emit(LspStoreEvent::RefreshCodeLens);
 9873        })?;
 9874        Ok(proto::Ack {})
 9875    }
 9876
 9877    async fn handle_open_buffer_for_symbol(
 9878        this: Entity<Self>,
 9879        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9880        mut cx: AsyncApp,
 9881    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9882        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9883        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9884        let symbol = Self::deserialize_symbol(symbol)?;
 9885        let symbol = this.read_with(&cx, |this, _| {
 9886            let signature = this.symbol_signature(&symbol.path);
 9887            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9888            Ok(symbol)
 9889        })??;
 9890        let buffer = this
 9891            .update(&mut cx, |this, cx| {
 9892                this.open_buffer_for_symbol(
 9893                    &Symbol {
 9894                        language_server_name: symbol.language_server_name,
 9895                        source_worktree_id: symbol.source_worktree_id,
 9896                        source_language_server_id: symbol.source_language_server_id,
 9897                        path: symbol.path,
 9898                        name: symbol.name,
 9899                        kind: symbol.kind,
 9900                        range: symbol.range,
 9901                        signature: symbol.signature,
 9902                        label: CodeLabel {
 9903                            text: Default::default(),
 9904                            runs: Default::default(),
 9905                            filter_range: Default::default(),
 9906                        },
 9907                    },
 9908                    cx,
 9909                )
 9910            })?
 9911            .await?;
 9912
 9913        this.update(&mut cx, |this, cx| {
 9914            let is_private = buffer
 9915                .read(cx)
 9916                .file()
 9917                .map(|f| f.is_private())
 9918                .unwrap_or_default();
 9919            if is_private {
 9920                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9921            } else {
 9922                this.buffer_store
 9923                    .update(cx, |buffer_store, cx| {
 9924                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9925                    })
 9926                    .detach_and_log_err(cx);
 9927                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9928                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9929            }
 9930        })?
 9931    }
 9932
 9933    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9934        let mut hasher = Sha256::new();
 9935        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9936        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9937        hasher.update(self.nonce.to_be_bytes());
 9938        hasher.finalize().as_slice().try_into().unwrap()
 9939    }
 9940
 9941    pub async fn handle_get_project_symbols(
 9942        this: Entity<Self>,
 9943        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9944        mut cx: AsyncApp,
 9945    ) -> Result<proto::GetProjectSymbolsResponse> {
 9946        let symbols = this
 9947            .update(&mut cx, |this, cx| {
 9948                this.symbols(&envelope.payload.query, cx)
 9949            })?
 9950            .await?;
 9951
 9952        Ok(proto::GetProjectSymbolsResponse {
 9953            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9954        })
 9955    }
 9956
 9957    pub async fn handle_restart_language_servers(
 9958        this: Entity<Self>,
 9959        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9960        mut cx: AsyncApp,
 9961    ) -> Result<proto::Ack> {
 9962        this.update(&mut cx, |lsp_store, cx| {
 9963            let buffers =
 9964                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9965            lsp_store.restart_language_servers_for_buffers(
 9966                buffers,
 9967                envelope
 9968                    .payload
 9969                    .only_servers
 9970                    .into_iter()
 9971                    .filter_map(|selector| {
 9972                        Some(match selector.selector? {
 9973                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9974                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9975                            }
 9976                            proto::language_server_selector::Selector::Name(name) => {
 9977                                LanguageServerSelector::Name(LanguageServerName(
 9978                                    SharedString::from(name),
 9979                                ))
 9980                            }
 9981                        })
 9982                    })
 9983                    .collect(),
 9984                cx,
 9985            );
 9986        })?;
 9987
 9988        Ok(proto::Ack {})
 9989    }
 9990
 9991    pub async fn handle_stop_language_servers(
 9992        lsp_store: Entity<Self>,
 9993        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9994        mut cx: AsyncApp,
 9995    ) -> Result<proto::Ack> {
 9996        lsp_store.update(&mut cx, |lsp_store, cx| {
 9997            if envelope.payload.all
 9998                && envelope.payload.also_servers.is_empty()
 9999                && envelope.payload.buffer_ids.is_empty()
10000            {
10001                lsp_store.stop_all_language_servers(cx);
10002            } else {
10003                let buffers =
10004                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10005                lsp_store
10006                    .stop_language_servers_for_buffers(
10007                        buffers,
10008                        envelope
10009                            .payload
10010                            .also_servers
10011                            .into_iter()
10012                            .filter_map(|selector| {
10013                                Some(match selector.selector? {
10014                                    proto::language_server_selector::Selector::ServerId(
10015                                        server_id,
10016                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10017                                        server_id,
10018                                    )),
10019                                    proto::language_server_selector::Selector::Name(name) => {
10020                                        LanguageServerSelector::Name(LanguageServerName(
10021                                            SharedString::from(name),
10022                                        ))
10023                                    }
10024                                })
10025                            })
10026                            .collect(),
10027                        cx,
10028                    )
10029                    .detach_and_log_err(cx);
10030            }
10031        })?;
10032
10033        Ok(proto::Ack {})
10034    }
10035
10036    pub async fn handle_cancel_language_server_work(
10037        this: Entity<Self>,
10038        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10039        mut cx: AsyncApp,
10040    ) -> Result<proto::Ack> {
10041        this.update(&mut cx, |this, cx| {
10042            if let Some(work) = envelope.payload.work {
10043                match work {
10044                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10045                        let buffers =
10046                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10047                        this.cancel_language_server_work_for_buffers(buffers, cx);
10048                    }
10049                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10050                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10051                        this.cancel_language_server_work(server_id, work.token, cx);
10052                    }
10053                }
10054            }
10055        })?;
10056
10057        Ok(proto::Ack {})
10058    }
10059
10060    fn buffer_ids_to_buffers(
10061        &mut self,
10062        buffer_ids: impl Iterator<Item = u64>,
10063        cx: &mut Context<Self>,
10064    ) -> Vec<Entity<Buffer>> {
10065        buffer_ids
10066            .into_iter()
10067            .flat_map(|buffer_id| {
10068                self.buffer_store
10069                    .read(cx)
10070                    .get(BufferId::new(buffer_id).log_err()?)
10071            })
10072            .collect::<Vec<_>>()
10073    }
10074
10075    async fn handle_apply_additional_edits_for_completion(
10076        this: Entity<Self>,
10077        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10078        mut cx: AsyncApp,
10079    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10080        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10081            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10082            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10083            let completion = Self::deserialize_completion(
10084                envelope.payload.completion.context("invalid completion")?,
10085            )?;
10086            anyhow::Ok((buffer, completion))
10087        })??;
10088
10089        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10090            this.apply_additional_edits_for_completion(
10091                buffer,
10092                Rc::new(RefCell::new(Box::new([Completion {
10093                    replace_range: completion.replace_range,
10094                    new_text: completion.new_text,
10095                    source: completion.source,
10096                    documentation: None,
10097                    label: CodeLabel {
10098                        text: Default::default(),
10099                        runs: Default::default(),
10100                        filter_range: Default::default(),
10101                    },
10102                    insert_text_mode: None,
10103                    icon_path: None,
10104                    confirm: None,
10105                }]))),
10106                0,
10107                false,
10108                cx,
10109            )
10110        })?;
10111
10112        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10113            transaction: apply_additional_edits
10114                .await?
10115                .as_ref()
10116                .map(language::proto::serialize_transaction),
10117        })
10118    }
10119
10120    pub fn last_formatting_failure(&self) -> Option<&str> {
10121        self.last_formatting_failure.as_deref()
10122    }
10123
10124    pub fn reset_last_formatting_failure(&mut self) {
10125        self.last_formatting_failure = None;
10126    }
10127
10128    pub fn environment_for_buffer(
10129        &self,
10130        buffer: &Entity<Buffer>,
10131        cx: &mut Context<Self>,
10132    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10133        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10134            environment.update(cx, |env, cx| {
10135                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10136            })
10137        } else {
10138            Task::ready(None).shared()
10139        }
10140    }
10141
10142    pub fn format(
10143        &mut self,
10144        buffers: HashSet<Entity<Buffer>>,
10145        target: LspFormatTarget,
10146        push_to_history: bool,
10147        trigger: FormatTrigger,
10148        cx: &mut Context<Self>,
10149    ) -> Task<anyhow::Result<ProjectTransaction>> {
10150        let logger = zlog::scoped!("format");
10151        if self.as_local().is_some() {
10152            zlog::trace!(logger => "Formatting locally");
10153            let logger = zlog::scoped!(logger => "local");
10154            let buffers = buffers
10155                .into_iter()
10156                .map(|buffer_handle| {
10157                    let buffer = buffer_handle.read(cx);
10158                    let buffer_abs_path = File::from_dyn(buffer.file())
10159                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10160
10161                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10162                })
10163                .collect::<Vec<_>>();
10164
10165            cx.spawn(async move |lsp_store, cx| {
10166                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10167
10168                for (handle, abs_path, id) in buffers {
10169                    let env = lsp_store
10170                        .update(cx, |lsp_store, cx| {
10171                            lsp_store.environment_for_buffer(&handle, cx)
10172                        })?
10173                        .await;
10174
10175                    let ranges = match &target {
10176                        LspFormatTarget::Buffers => None,
10177                        LspFormatTarget::Ranges(ranges) => {
10178                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10179                        }
10180                    };
10181
10182                    formattable_buffers.push(FormattableBuffer {
10183                        handle,
10184                        abs_path,
10185                        env,
10186                        ranges,
10187                    });
10188                }
10189                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10190
10191                let format_timer = zlog::time!(logger => "Formatting buffers");
10192                let result = LocalLspStore::format_locally(
10193                    lsp_store.clone(),
10194                    formattable_buffers,
10195                    push_to_history,
10196                    trigger,
10197                    logger,
10198                    cx,
10199                )
10200                .await;
10201                format_timer.end();
10202
10203                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10204
10205                lsp_store.update(cx, |lsp_store, _| {
10206                    lsp_store.update_last_formatting_failure(&result);
10207                })?;
10208
10209                result
10210            })
10211        } else if let Some((client, project_id)) = self.upstream_client() {
10212            zlog::trace!(logger => "Formatting remotely");
10213            let logger = zlog::scoped!(logger => "remote");
10214            // Don't support formatting ranges via remote
10215            match target {
10216                LspFormatTarget::Buffers => {}
10217                LspFormatTarget::Ranges(_) => {
10218                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10219                    return Task::ready(Ok(ProjectTransaction::default()));
10220                }
10221            }
10222
10223            let buffer_store = self.buffer_store();
10224            cx.spawn(async move |lsp_store, cx| {
10225                zlog::trace!(logger => "Sending remote format request");
10226                let request_timer = zlog::time!(logger => "remote format request");
10227                let result = client
10228                    .request(proto::FormatBuffers {
10229                        project_id,
10230                        trigger: trigger as i32,
10231                        buffer_ids: buffers
10232                            .iter()
10233                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10234                            .collect::<Result<_>>()?,
10235                    })
10236                    .await
10237                    .and_then(|result| result.transaction.context("missing transaction"));
10238                request_timer.end();
10239
10240                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10241
10242                lsp_store.update(cx, |lsp_store, _| {
10243                    lsp_store.update_last_formatting_failure(&result);
10244                })?;
10245
10246                let transaction_response = result?;
10247                let _timer = zlog::time!(logger => "deserializing project transaction");
10248                buffer_store
10249                    .update(cx, |buffer_store, cx| {
10250                        buffer_store.deserialize_project_transaction(
10251                            transaction_response,
10252                            push_to_history,
10253                            cx,
10254                        )
10255                    })?
10256                    .await
10257            })
10258        } else {
10259            zlog::trace!(logger => "Not formatting");
10260            Task::ready(Ok(ProjectTransaction::default()))
10261        }
10262    }
10263
10264    async fn handle_format_buffers(
10265        this: Entity<Self>,
10266        envelope: TypedEnvelope<proto::FormatBuffers>,
10267        mut cx: AsyncApp,
10268    ) -> Result<proto::FormatBuffersResponse> {
10269        let sender_id = envelope.original_sender_id().unwrap_or_default();
10270        let format = this.update(&mut cx, |this, cx| {
10271            let mut buffers = HashSet::default();
10272            for buffer_id in &envelope.payload.buffer_ids {
10273                let buffer_id = BufferId::new(*buffer_id)?;
10274                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10275            }
10276            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10277            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10278        })??;
10279
10280        let project_transaction = format.await?;
10281        let project_transaction = this.update(&mut cx, |this, cx| {
10282            this.buffer_store.update(cx, |buffer_store, cx| {
10283                buffer_store.serialize_project_transaction_for_peer(
10284                    project_transaction,
10285                    sender_id,
10286                    cx,
10287                )
10288            })
10289        })?;
10290        Ok(proto::FormatBuffersResponse {
10291            transaction: Some(project_transaction),
10292        })
10293    }
10294
10295    async fn handle_apply_code_action_kind(
10296        this: Entity<Self>,
10297        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10298        mut cx: AsyncApp,
10299    ) -> Result<proto::ApplyCodeActionKindResponse> {
10300        let sender_id = envelope.original_sender_id().unwrap_or_default();
10301        let format = this.update(&mut cx, |this, cx| {
10302            let mut buffers = HashSet::default();
10303            for buffer_id in &envelope.payload.buffer_ids {
10304                let buffer_id = BufferId::new(*buffer_id)?;
10305                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10306            }
10307            let kind = match envelope.payload.kind.as_str() {
10308                "" => CodeActionKind::EMPTY,
10309                "quickfix" => CodeActionKind::QUICKFIX,
10310                "refactor" => CodeActionKind::REFACTOR,
10311                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10312                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10313                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10314                "source" => CodeActionKind::SOURCE,
10315                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10316                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10317                _ => anyhow::bail!(
10318                    "Invalid code action kind {}",
10319                    envelope.payload.kind.as_str()
10320                ),
10321            };
10322            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10323        })??;
10324
10325        let project_transaction = format.await?;
10326        let project_transaction = this.update(&mut cx, |this, cx| {
10327            this.buffer_store.update(cx, |buffer_store, cx| {
10328                buffer_store.serialize_project_transaction_for_peer(
10329                    project_transaction,
10330                    sender_id,
10331                    cx,
10332                )
10333            })
10334        })?;
10335        Ok(proto::ApplyCodeActionKindResponse {
10336            transaction: Some(project_transaction),
10337        })
10338    }
10339
10340    async fn shutdown_language_server(
10341        server_state: Option<LanguageServerState>,
10342        name: LanguageServerName,
10343        cx: &mut AsyncApp,
10344    ) {
10345        let server = match server_state {
10346            Some(LanguageServerState::Starting { startup, .. }) => {
10347                let mut timer = cx
10348                    .background_executor()
10349                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10350                    .fuse();
10351
10352                select! {
10353                    server = startup.fuse() => server,
10354                    () = timer => {
10355                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10356                        None
10357                    },
10358                }
10359            }
10360
10361            Some(LanguageServerState::Running { server, .. }) => Some(server),
10362
10363            None => None,
10364        };
10365
10366        if let Some(server) = server
10367            && let Some(shutdown) = server.shutdown()
10368        {
10369            shutdown.await;
10370        }
10371    }
10372
10373    // Returns a list of all of the worktrees which no longer have a language server and the root path
10374    // for the stopped server
10375    fn stop_local_language_server(
10376        &mut self,
10377        server_id: LanguageServerId,
10378        cx: &mut Context<Self>,
10379    ) -> Task<()> {
10380        let local = match &mut self.mode {
10381            LspStoreMode::Local(local) => local,
10382            _ => {
10383                return Task::ready(());
10384            }
10385        };
10386
10387        // Remove this server ID from all entries in the given worktree.
10388        local
10389            .language_server_ids
10390            .retain(|_, state| state.id != server_id);
10391        self.buffer_store.update(cx, |buffer_store, cx| {
10392            for buffer in buffer_store.buffers() {
10393                buffer.update(cx, |buffer, cx| {
10394                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10395                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10396                });
10397            }
10398        });
10399
10400        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10401            summaries.retain(|path, summaries_by_server_id| {
10402                if summaries_by_server_id.remove(&server_id).is_some() {
10403                    if let Some((client, project_id)) = self.downstream_client.clone() {
10404                        client
10405                            .send(proto::UpdateDiagnosticSummary {
10406                                project_id,
10407                                worktree_id: worktree_id.to_proto(),
10408                                summary: Some(proto::DiagnosticSummary {
10409                                    path: path.as_ref().to_proto(),
10410                                    language_server_id: server_id.0 as u64,
10411                                    error_count: 0,
10412                                    warning_count: 0,
10413                                }),
10414                                more_summaries: Vec::new(),
10415                            })
10416                            .log_err();
10417                    }
10418                    !summaries_by_server_id.is_empty()
10419                } else {
10420                    true
10421                }
10422            });
10423        }
10424
10425        let local = self.as_local_mut().unwrap();
10426        for diagnostics in local.diagnostics.values_mut() {
10427            diagnostics.retain(|_, diagnostics_by_server_id| {
10428                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10429                    diagnostics_by_server_id.remove(ix);
10430                    !diagnostics_by_server_id.is_empty()
10431                } else {
10432                    true
10433                }
10434            });
10435        }
10436        local.language_server_watched_paths.remove(&server_id);
10437
10438        let server_state = local.language_servers.remove(&server_id);
10439        self.cleanup_lsp_data(server_id);
10440        let name = self
10441            .language_server_statuses
10442            .remove(&server_id)
10443            .map(|status| status.name)
10444            .or_else(|| {
10445                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10446                    Some(adapter.name())
10447                } else {
10448                    None
10449                }
10450            });
10451
10452        if let Some(name) = name {
10453            log::info!("stopping language server {name}");
10454            self.languages
10455                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10456            cx.notify();
10457
10458            return cx.spawn(async move |lsp_store, cx| {
10459                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10460                lsp_store
10461                    .update(cx, |lsp_store, cx| {
10462                        lsp_store
10463                            .languages
10464                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10465                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10466                        cx.notify();
10467                    })
10468                    .ok();
10469            });
10470        }
10471
10472        if server_state.is_some() {
10473            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10474        }
10475        Task::ready(())
10476    }
10477
10478    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10479        if let Some((client, project_id)) = self.upstream_client() {
10480            let request = client.request(proto::StopLanguageServers {
10481                project_id,
10482                buffer_ids: Vec::new(),
10483                also_servers: Vec::new(),
10484                all: true,
10485            });
10486            cx.background_spawn(request).detach_and_log_err(cx);
10487        } else {
10488            let Some(local) = self.as_local_mut() else {
10489                return;
10490            };
10491            let language_servers_to_stop = local
10492                .language_server_ids
10493                .values()
10494                .map(|state| state.id)
10495                .collect();
10496            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10497            let tasks = language_servers_to_stop
10498                .into_iter()
10499                .map(|server| self.stop_local_language_server(server, cx))
10500                .collect::<Vec<_>>();
10501            cx.background_spawn(async move {
10502                futures::future::join_all(tasks).await;
10503            })
10504            .detach();
10505        }
10506    }
10507
10508    pub fn restart_language_servers_for_buffers(
10509        &mut self,
10510        buffers: Vec<Entity<Buffer>>,
10511        only_restart_servers: HashSet<LanguageServerSelector>,
10512        cx: &mut Context<Self>,
10513    ) {
10514        if let Some((client, project_id)) = self.upstream_client() {
10515            let request = client.request(proto::RestartLanguageServers {
10516                project_id,
10517                buffer_ids: buffers
10518                    .into_iter()
10519                    .map(|b| b.read(cx).remote_id().to_proto())
10520                    .collect(),
10521                only_servers: only_restart_servers
10522                    .into_iter()
10523                    .map(|selector| {
10524                        let selector = match selector {
10525                            LanguageServerSelector::Id(language_server_id) => {
10526                                proto::language_server_selector::Selector::ServerId(
10527                                    language_server_id.to_proto(),
10528                                )
10529                            }
10530                            LanguageServerSelector::Name(language_server_name) => {
10531                                proto::language_server_selector::Selector::Name(
10532                                    language_server_name.to_string(),
10533                                )
10534                            }
10535                        };
10536                        proto::LanguageServerSelector {
10537                            selector: Some(selector),
10538                        }
10539                    })
10540                    .collect(),
10541                all: false,
10542            });
10543            cx.background_spawn(request).detach_and_log_err(cx);
10544        } else {
10545            let stop_task = if only_restart_servers.is_empty() {
10546                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10547            } else {
10548                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10549            };
10550            cx.spawn(async move |lsp_store, cx| {
10551                stop_task.await;
10552                lsp_store
10553                    .update(cx, |lsp_store, cx| {
10554                        for buffer in buffers {
10555                            lsp_store.register_buffer_with_language_servers(
10556                                &buffer,
10557                                only_restart_servers.clone(),
10558                                true,
10559                                cx,
10560                            );
10561                        }
10562                    })
10563                    .ok()
10564            })
10565            .detach();
10566        }
10567    }
10568
10569    pub fn stop_language_servers_for_buffers(
10570        &mut self,
10571        buffers: Vec<Entity<Buffer>>,
10572        also_stop_servers: HashSet<LanguageServerSelector>,
10573        cx: &mut Context<Self>,
10574    ) -> Task<Result<()>> {
10575        if let Some((client, project_id)) = self.upstream_client() {
10576            let request = client.request(proto::StopLanguageServers {
10577                project_id,
10578                buffer_ids: buffers
10579                    .into_iter()
10580                    .map(|b| b.read(cx).remote_id().to_proto())
10581                    .collect(),
10582                also_servers: also_stop_servers
10583                    .into_iter()
10584                    .map(|selector| {
10585                        let selector = match selector {
10586                            LanguageServerSelector::Id(language_server_id) => {
10587                                proto::language_server_selector::Selector::ServerId(
10588                                    language_server_id.to_proto(),
10589                                )
10590                            }
10591                            LanguageServerSelector::Name(language_server_name) => {
10592                                proto::language_server_selector::Selector::Name(
10593                                    language_server_name.to_string(),
10594                                )
10595                            }
10596                        };
10597                        proto::LanguageServerSelector {
10598                            selector: Some(selector),
10599                        }
10600                    })
10601                    .collect(),
10602                all: false,
10603            });
10604            cx.background_spawn(async move {
10605                let _ = request.await?;
10606                Ok(())
10607            })
10608        } else {
10609            let task =
10610                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10611            cx.background_spawn(async move {
10612                task.await;
10613                Ok(())
10614            })
10615        }
10616    }
10617
10618    fn stop_local_language_servers_for_buffers(
10619        &mut self,
10620        buffers: &[Entity<Buffer>],
10621        also_stop_servers: HashSet<LanguageServerSelector>,
10622        cx: &mut Context<Self>,
10623    ) -> Task<()> {
10624        let Some(local) = self.as_local_mut() else {
10625            return Task::ready(());
10626        };
10627        let mut language_server_names_to_stop = BTreeSet::default();
10628        let mut language_servers_to_stop = also_stop_servers
10629            .into_iter()
10630            .flat_map(|selector| match selector {
10631                LanguageServerSelector::Id(id) => Some(id),
10632                LanguageServerSelector::Name(name) => {
10633                    language_server_names_to_stop.insert(name);
10634                    None
10635                }
10636            })
10637            .collect::<BTreeSet<_>>();
10638
10639        let mut covered_worktrees = HashSet::default();
10640        for buffer in buffers {
10641            buffer.update(cx, |buffer, cx| {
10642                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10643                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10644                    && covered_worktrees.insert(worktree_id)
10645                {
10646                    language_server_names_to_stop.retain(|name| {
10647                        let old_ids_count = language_servers_to_stop.len();
10648                        let all_language_servers_with_this_name = local
10649                            .language_server_ids
10650                            .iter()
10651                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10652                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10653                        old_ids_count == language_servers_to_stop.len()
10654                    });
10655                }
10656            });
10657        }
10658        for name in language_server_names_to_stop {
10659            language_servers_to_stop.extend(
10660                local
10661                    .language_server_ids
10662                    .iter()
10663                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10664            );
10665        }
10666
10667        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10668        let tasks = language_servers_to_stop
10669            .into_iter()
10670            .map(|server| self.stop_local_language_server(server, cx))
10671            .collect::<Vec<_>>();
10672
10673        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10674    }
10675
10676    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10677        let (worktree, relative_path) =
10678            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10679
10680        let project_path = ProjectPath {
10681            worktree_id: worktree.read(cx).id(),
10682            path: relative_path.into(),
10683        };
10684
10685        Some(
10686            self.buffer_store()
10687                .read(cx)
10688                .get_by_path(&project_path)?
10689                .read(cx),
10690        )
10691    }
10692
10693    #[cfg(any(test, feature = "test-support"))]
10694    pub fn update_diagnostics(
10695        &mut self,
10696        server_id: LanguageServerId,
10697        diagnostics: lsp::PublishDiagnosticsParams,
10698        result_id: Option<String>,
10699        source_kind: DiagnosticSourceKind,
10700        disk_based_sources: &[String],
10701        cx: &mut Context<Self>,
10702    ) -> Result<()> {
10703        self.merge_lsp_diagnostics(
10704            source_kind,
10705            vec![DocumentDiagnosticsUpdate {
10706                diagnostics,
10707                result_id,
10708                server_id,
10709                disk_based_sources: Cow::Borrowed(disk_based_sources),
10710            }],
10711            |_, _, _| false,
10712            cx,
10713        )
10714    }
10715
10716    pub fn merge_lsp_diagnostics(
10717        &mut self,
10718        source_kind: DiagnosticSourceKind,
10719        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10720        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10721        cx: &mut Context<Self>,
10722    ) -> Result<()> {
10723        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10724        let updates = lsp_diagnostics
10725            .into_iter()
10726            .filter_map(|update| {
10727                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10728                Some(DocumentDiagnosticsUpdate {
10729                    diagnostics: self.lsp_to_document_diagnostics(
10730                        abs_path,
10731                        source_kind,
10732                        update.server_id,
10733                        update.diagnostics,
10734                        &update.disk_based_sources,
10735                    ),
10736                    result_id: update.result_id,
10737                    server_id: update.server_id,
10738                    disk_based_sources: update.disk_based_sources,
10739                })
10740            })
10741            .collect();
10742        self.merge_diagnostic_entries(updates, merge, cx)?;
10743        Ok(())
10744    }
10745
10746    fn lsp_to_document_diagnostics(
10747        &mut self,
10748        document_abs_path: PathBuf,
10749        source_kind: DiagnosticSourceKind,
10750        server_id: LanguageServerId,
10751        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10752        disk_based_sources: &[String],
10753    ) -> DocumentDiagnostics {
10754        let mut diagnostics = Vec::default();
10755        let mut primary_diagnostic_group_ids = HashMap::default();
10756        let mut sources_by_group_id = HashMap::default();
10757        let mut supporting_diagnostics = HashMap::default();
10758
10759        let adapter = self.language_server_adapter_for_id(server_id);
10760
10761        // Ensure that primary diagnostics are always the most severe
10762        lsp_diagnostics
10763            .diagnostics
10764            .sort_by_key(|item| item.severity);
10765
10766        for diagnostic in &lsp_diagnostics.diagnostics {
10767            let source = diagnostic.source.as_ref();
10768            let range = range_from_lsp(diagnostic.range);
10769            let is_supporting = diagnostic
10770                .related_information
10771                .as_ref()
10772                .is_some_and(|infos| {
10773                    infos.iter().any(|info| {
10774                        primary_diagnostic_group_ids.contains_key(&(
10775                            source,
10776                            diagnostic.code.clone(),
10777                            range_from_lsp(info.location.range),
10778                        ))
10779                    })
10780                });
10781
10782            let is_unnecessary = diagnostic
10783                .tags
10784                .as_ref()
10785                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10786
10787            let underline = self
10788                .language_server_adapter_for_id(server_id)
10789                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10790
10791            if is_supporting {
10792                supporting_diagnostics.insert(
10793                    (source, diagnostic.code.clone(), range),
10794                    (diagnostic.severity, is_unnecessary),
10795                );
10796            } else {
10797                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10798                let is_disk_based =
10799                    source.is_some_and(|source| disk_based_sources.contains(source));
10800
10801                sources_by_group_id.insert(group_id, source);
10802                primary_diagnostic_group_ids
10803                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10804
10805                diagnostics.push(DiagnosticEntry {
10806                    range,
10807                    diagnostic: Diagnostic {
10808                        source: diagnostic.source.clone(),
10809                        source_kind,
10810                        code: diagnostic.code.clone(),
10811                        code_description: diagnostic
10812                            .code_description
10813                            .as_ref()
10814                            .and_then(|d| d.href.clone()),
10815                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10816                        markdown: adapter.as_ref().and_then(|adapter| {
10817                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10818                        }),
10819                        message: diagnostic.message.trim().to_string(),
10820                        group_id,
10821                        is_primary: true,
10822                        is_disk_based,
10823                        is_unnecessary,
10824                        underline,
10825                        data: diagnostic.data.clone(),
10826                    },
10827                });
10828                if let Some(infos) = &diagnostic.related_information {
10829                    for info in infos {
10830                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10831                            let range = range_from_lsp(info.location.range);
10832                            diagnostics.push(DiagnosticEntry {
10833                                range,
10834                                diagnostic: Diagnostic {
10835                                    source: diagnostic.source.clone(),
10836                                    source_kind,
10837                                    code: diagnostic.code.clone(),
10838                                    code_description: diagnostic
10839                                        .code_description
10840                                        .as_ref()
10841                                        .and_then(|d| d.href.clone()),
10842                                    severity: DiagnosticSeverity::INFORMATION,
10843                                    markdown: adapter.as_ref().and_then(|adapter| {
10844                                        adapter.diagnostic_message_to_markdown(&info.message)
10845                                    }),
10846                                    message: info.message.trim().to_string(),
10847                                    group_id,
10848                                    is_primary: false,
10849                                    is_disk_based,
10850                                    is_unnecessary: false,
10851                                    underline,
10852                                    data: diagnostic.data.clone(),
10853                                },
10854                            });
10855                        }
10856                    }
10857                }
10858            }
10859        }
10860
10861        for entry in &mut diagnostics {
10862            let diagnostic = &mut entry.diagnostic;
10863            if !diagnostic.is_primary {
10864                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10865                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10866                    source,
10867                    diagnostic.code.clone(),
10868                    entry.range.clone(),
10869                )) {
10870                    if let Some(severity) = severity {
10871                        diagnostic.severity = severity;
10872                    }
10873                    diagnostic.is_unnecessary = is_unnecessary;
10874                }
10875            }
10876        }
10877
10878        DocumentDiagnostics {
10879            diagnostics,
10880            document_abs_path,
10881            version: lsp_diagnostics.version,
10882        }
10883    }
10884
10885    fn insert_newly_running_language_server(
10886        &mut self,
10887        adapter: Arc<CachedLspAdapter>,
10888        language_server: Arc<LanguageServer>,
10889        server_id: LanguageServerId,
10890        key: LanguageServerSeed,
10891        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10892        cx: &mut Context<Self>,
10893    ) {
10894        let Some(local) = self.as_local_mut() else {
10895            return;
10896        };
10897        // If the language server for this key doesn't match the server id, don't store the
10898        // server. Which will cause it to be dropped, killing the process
10899        if local
10900            .language_server_ids
10901            .get(&key)
10902            .map(|state| state.id != server_id)
10903            .unwrap_or(false)
10904        {
10905            return;
10906        }
10907
10908        // Update language_servers collection with Running variant of LanguageServerState
10909        // indicating that the server is up and running and ready
10910        let workspace_folders = workspace_folders.lock().clone();
10911        language_server.set_workspace_folders(workspace_folders);
10912
10913        local.language_servers.insert(
10914            server_id,
10915            LanguageServerState::Running {
10916                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10917                    language_server.clone(),
10918                    cx,
10919                ),
10920                adapter: adapter.clone(),
10921                server: language_server.clone(),
10922                simulate_disk_based_diagnostics_completion: None,
10923            },
10924        );
10925        local
10926            .languages
10927            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10928        if let Some(file_ops_caps) = language_server
10929            .capabilities()
10930            .workspace
10931            .as_ref()
10932            .and_then(|ws| ws.file_operations.as_ref())
10933        {
10934            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10935            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10936            if did_rename_caps.or(will_rename_caps).is_some() {
10937                let watcher = RenamePathsWatchedForServer::default()
10938                    .with_did_rename_patterns(did_rename_caps)
10939                    .with_will_rename_patterns(will_rename_caps);
10940                local
10941                    .language_server_paths_watched_for_rename
10942                    .insert(server_id, watcher);
10943            }
10944        }
10945
10946        self.language_server_statuses.insert(
10947            server_id,
10948            LanguageServerStatus {
10949                name: language_server.name(),
10950                pending_work: Default::default(),
10951                has_pending_diagnostic_updates: false,
10952                progress_tokens: Default::default(),
10953                worktree: Some(key.worktree_id),
10954            },
10955        );
10956
10957        cx.emit(LspStoreEvent::LanguageServerAdded(
10958            server_id,
10959            language_server.name(),
10960            Some(key.worktree_id),
10961        ));
10962        cx.emit(LspStoreEvent::RefreshInlayHints);
10963
10964        let server_capabilities = language_server.capabilities();
10965        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10966            downstream_client
10967                .send(proto::StartLanguageServer {
10968                    project_id: *project_id,
10969                    server: Some(proto::LanguageServer {
10970                        id: server_id.to_proto(),
10971                        name: language_server.name().to_string(),
10972                        worktree_id: Some(key.worktree_id.to_proto()),
10973                    }),
10974                    capabilities: serde_json::to_string(&server_capabilities)
10975                        .expect("serializing server LSP capabilities"),
10976                })
10977                .log_err();
10978        }
10979        self.lsp_server_capabilities
10980            .insert(server_id, server_capabilities);
10981
10982        // Tell the language server about every open buffer in the worktree that matches the language.
10983        // Also check for buffers in worktrees that reused this server
10984        let mut worktrees_using_server = vec![key.worktree_id];
10985        if let Some(local) = self.as_local() {
10986            // Find all worktrees that have this server in their language server tree
10987            for (worktree_id, servers) in &local.lsp_tree.instances {
10988                if *worktree_id != key.worktree_id {
10989                    for server_map in servers.roots.values() {
10990                        if server_map.contains_key(&key.name) {
10991                            worktrees_using_server.push(*worktree_id);
10992                        }
10993                    }
10994                }
10995            }
10996        }
10997
10998        let mut buffer_paths_registered = Vec::new();
10999        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11000            for buffer_handle in buffer_store.buffers() {
11001                let buffer = buffer_handle.read(cx);
11002                let file = match File::from_dyn(buffer.file()) {
11003                    Some(file) => file,
11004                    None => continue,
11005                };
11006                let language = match buffer.language() {
11007                    Some(language) => language,
11008                    None => continue,
11009                };
11010
11011                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11012                    || !self
11013                        .languages
11014                        .lsp_adapters(&language.name())
11015                        .iter()
11016                        .any(|a| a.name == key.name)
11017                {
11018                    continue;
11019                }
11020                // didOpen
11021                let file = match file.as_local() {
11022                    Some(file) => file,
11023                    None => continue,
11024                };
11025
11026                let local = self.as_local_mut().unwrap();
11027
11028                let buffer_id = buffer.remote_id();
11029                if local.registered_buffers.contains_key(&buffer_id) {
11030                    let versions = local
11031                        .buffer_snapshots
11032                        .entry(buffer_id)
11033                        .or_default()
11034                        .entry(server_id)
11035                        .and_modify(|_| {
11036                            assert!(
11037                            false,
11038                            "There should not be an existing snapshot for a newly inserted buffer"
11039                        )
11040                        })
11041                        .or_insert_with(|| {
11042                            vec![LspBufferSnapshot {
11043                                version: 0,
11044                                snapshot: buffer.text_snapshot(),
11045                            }]
11046                        });
11047
11048                    let snapshot = versions.last().unwrap();
11049                    let version = snapshot.version;
11050                    let initial_snapshot = &snapshot.snapshot;
11051                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11052                    language_server.register_buffer(
11053                        uri,
11054                        adapter.language_id(&language.name()),
11055                        version,
11056                        initial_snapshot.text(),
11057                    );
11058                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11059                    local
11060                        .buffers_opened_in_servers
11061                        .entry(buffer_id)
11062                        .or_default()
11063                        .insert(server_id);
11064                }
11065                buffer_handle.update(cx, |buffer, cx| {
11066                    buffer.set_completion_triggers(
11067                        server_id,
11068                        language_server
11069                            .capabilities()
11070                            .completion_provider
11071                            .as_ref()
11072                            .and_then(|provider| {
11073                                provider
11074                                    .trigger_characters
11075                                    .as_ref()
11076                                    .map(|characters| characters.iter().cloned().collect())
11077                            })
11078                            .unwrap_or_default(),
11079                        cx,
11080                    )
11081                });
11082            }
11083        });
11084
11085        for (buffer_id, abs_path) in buffer_paths_registered {
11086            cx.emit(LspStoreEvent::LanguageServerUpdate {
11087                language_server_id: server_id,
11088                name: Some(adapter.name()),
11089                message: proto::update_language_server::Variant::RegisteredForBuffer(
11090                    proto::RegisteredForBuffer {
11091                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
11092                        buffer_id: buffer_id.to_proto(),
11093                    },
11094                ),
11095            });
11096        }
11097
11098        cx.notify();
11099    }
11100
11101    pub fn language_servers_running_disk_based_diagnostics(
11102        &self,
11103    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11104        self.language_server_statuses
11105            .iter()
11106            .filter_map(|(id, status)| {
11107                if status.has_pending_diagnostic_updates {
11108                    Some(*id)
11109                } else {
11110                    None
11111                }
11112            })
11113    }
11114
11115    pub(crate) fn cancel_language_server_work_for_buffers(
11116        &mut self,
11117        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11118        cx: &mut Context<Self>,
11119    ) {
11120        if let Some((client, project_id)) = self.upstream_client() {
11121            let request = client.request(proto::CancelLanguageServerWork {
11122                project_id,
11123                work: Some(proto::cancel_language_server_work::Work::Buffers(
11124                    proto::cancel_language_server_work::Buffers {
11125                        buffer_ids: buffers
11126                            .into_iter()
11127                            .map(|b| b.read(cx).remote_id().to_proto())
11128                            .collect(),
11129                    },
11130                )),
11131            });
11132            cx.background_spawn(request).detach_and_log_err(cx);
11133        } else if let Some(local) = self.as_local() {
11134            let servers = buffers
11135                .into_iter()
11136                .flat_map(|buffer| {
11137                    buffer.update(cx, |buffer, cx| {
11138                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11139                    })
11140                })
11141                .collect::<HashSet<_>>();
11142            for server_id in servers {
11143                self.cancel_language_server_work(server_id, None, cx);
11144            }
11145        }
11146    }
11147
11148    pub(crate) fn cancel_language_server_work(
11149        &mut self,
11150        server_id: LanguageServerId,
11151        token_to_cancel: Option<String>,
11152        cx: &mut Context<Self>,
11153    ) {
11154        if let Some(local) = self.as_local() {
11155            let status = self.language_server_statuses.get(&server_id);
11156            let server = local.language_servers.get(&server_id);
11157            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11158            {
11159                for (token, progress) in &status.pending_work {
11160                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11161                        && token != token_to_cancel
11162                    {
11163                        continue;
11164                    }
11165                    if progress.is_cancellable {
11166                        server
11167                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11168                                &WorkDoneProgressCancelParams {
11169                                    token: lsp::NumberOrString::String(token.clone()),
11170                                },
11171                            )
11172                            .ok();
11173                    }
11174                }
11175            }
11176        } else if let Some((client, project_id)) = self.upstream_client() {
11177            let request = client.request(proto::CancelLanguageServerWork {
11178                project_id,
11179                work: Some(
11180                    proto::cancel_language_server_work::Work::LanguageServerWork(
11181                        proto::cancel_language_server_work::LanguageServerWork {
11182                            language_server_id: server_id.to_proto(),
11183                            token: token_to_cancel,
11184                        },
11185                    ),
11186                ),
11187            });
11188            cx.background_spawn(request).detach_and_log_err(cx);
11189        }
11190    }
11191
11192    fn register_supplementary_language_server(
11193        &mut self,
11194        id: LanguageServerId,
11195        name: LanguageServerName,
11196        server: Arc<LanguageServer>,
11197        cx: &mut Context<Self>,
11198    ) {
11199        if let Some(local) = self.as_local_mut() {
11200            local
11201                .supplementary_language_servers
11202                .insert(id, (name.clone(), server));
11203            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11204        }
11205    }
11206
11207    fn unregister_supplementary_language_server(
11208        &mut self,
11209        id: LanguageServerId,
11210        cx: &mut Context<Self>,
11211    ) {
11212        if let Some(local) = self.as_local_mut() {
11213            local.supplementary_language_servers.remove(&id);
11214            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11215        }
11216    }
11217
11218    pub(crate) fn supplementary_language_servers(
11219        &self,
11220    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11221        self.as_local().into_iter().flat_map(|local| {
11222            local
11223                .supplementary_language_servers
11224                .iter()
11225                .map(|(id, (name, _))| (*id, name.clone()))
11226        })
11227    }
11228
11229    pub fn language_server_adapter_for_id(
11230        &self,
11231        id: LanguageServerId,
11232    ) -> Option<Arc<CachedLspAdapter>> {
11233        self.as_local()
11234            .and_then(|local| local.language_servers.get(&id))
11235            .and_then(|language_server_state| match language_server_state {
11236                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11237                _ => None,
11238            })
11239    }
11240
11241    pub(super) fn update_local_worktree_language_servers(
11242        &mut self,
11243        worktree_handle: &Entity<Worktree>,
11244        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
11245        cx: &mut Context<Self>,
11246    ) {
11247        if changes.is_empty() {
11248            return;
11249        }
11250
11251        let Some(local) = self.as_local() else { return };
11252
11253        local.prettier_store.update(cx, |prettier_store, cx| {
11254            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11255        });
11256
11257        let worktree_id = worktree_handle.read(cx).id();
11258        let mut language_server_ids = local
11259            .language_server_ids
11260            .iter()
11261            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11262            .collect::<Vec<_>>();
11263        language_server_ids.sort();
11264        language_server_ids.dedup();
11265
11266        let abs_path = worktree_handle.read(cx).abs_path();
11267        for server_id in &language_server_ids {
11268            if let Some(LanguageServerState::Running { server, .. }) =
11269                local.language_servers.get(server_id)
11270                && let Some(watched_paths) = local
11271                    .language_server_watched_paths
11272                    .get(server_id)
11273                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11274            {
11275                let params = lsp::DidChangeWatchedFilesParams {
11276                    changes: changes
11277                        .iter()
11278                        .filter_map(|(path, _, change)| {
11279                            if !watched_paths.is_match(path) {
11280                                return None;
11281                            }
11282                            let typ = match change {
11283                                PathChange::Loaded => return None,
11284                                PathChange::Added => lsp::FileChangeType::CREATED,
11285                                PathChange::Removed => lsp::FileChangeType::DELETED,
11286                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11287                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11288                            };
11289                            Some(lsp::FileEvent {
11290                                uri: lsp::Uri::from_file_path(abs_path.join(path)).unwrap(),
11291                                typ,
11292                            })
11293                        })
11294                        .collect(),
11295                };
11296                if !params.changes.is_empty() {
11297                    server
11298                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
11299                        .ok();
11300                }
11301            }
11302        }
11303        for (path, _, _) in changes {
11304            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
11305                && local.watched_manifest_filenames.contains(file_name)
11306            {
11307                self.request_workspace_config_refresh();
11308                break;
11309            }
11310        }
11311    }
11312
11313    pub fn wait_for_remote_buffer(
11314        &mut self,
11315        id: BufferId,
11316        cx: &mut Context<Self>,
11317    ) -> Task<Result<Entity<Buffer>>> {
11318        self.buffer_store.update(cx, |buffer_store, cx| {
11319            buffer_store.wait_for_remote_buffer(id, cx)
11320        })
11321    }
11322
11323    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11324        proto::Symbol {
11325            language_server_name: symbol.language_server_name.0.to_string(),
11326            source_worktree_id: symbol.source_worktree_id.to_proto(),
11327            language_server_id: symbol.source_language_server_id.to_proto(),
11328            worktree_id: symbol.path.worktree_id.to_proto(),
11329            path: symbol.path.path.as_ref().to_proto(),
11330            name: symbol.name.clone(),
11331            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11332            start: Some(proto::PointUtf16 {
11333                row: symbol.range.start.0.row,
11334                column: symbol.range.start.0.column,
11335            }),
11336            end: Some(proto::PointUtf16 {
11337                row: symbol.range.end.0.row,
11338                column: symbol.range.end.0.column,
11339            }),
11340            signature: symbol.signature.to_vec(),
11341        }
11342    }
11343
11344    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11345        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11346        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11347        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11348        let path = ProjectPath {
11349            worktree_id,
11350            path: Arc::<Path>::from_proto(serialized_symbol.path),
11351        };
11352
11353        let start = serialized_symbol.start.context("invalid start")?;
11354        let end = serialized_symbol.end.context("invalid end")?;
11355        Ok(CoreSymbol {
11356            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11357            source_worktree_id,
11358            source_language_server_id: LanguageServerId::from_proto(
11359                serialized_symbol.language_server_id,
11360            ),
11361            path,
11362            name: serialized_symbol.name,
11363            range: Unclipped(PointUtf16::new(start.row, start.column))
11364                ..Unclipped(PointUtf16::new(end.row, end.column)),
11365            kind,
11366            signature: serialized_symbol
11367                .signature
11368                .try_into()
11369                .map_err(|_| anyhow!("invalid signature"))?,
11370        })
11371    }
11372
11373    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11374        let mut serialized_completion = proto::Completion {
11375            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11376            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11377            new_text: completion.new_text.clone(),
11378            ..proto::Completion::default()
11379        };
11380        match &completion.source {
11381            CompletionSource::Lsp {
11382                insert_range,
11383                server_id,
11384                lsp_completion,
11385                lsp_defaults,
11386                resolved,
11387            } => {
11388                let (old_insert_start, old_insert_end) = insert_range
11389                    .as_ref()
11390                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11391                    .unzip();
11392
11393                serialized_completion.old_insert_start = old_insert_start;
11394                serialized_completion.old_insert_end = old_insert_end;
11395                serialized_completion.source = proto::completion::Source::Lsp as i32;
11396                serialized_completion.server_id = server_id.0 as u64;
11397                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11398                serialized_completion.lsp_defaults = lsp_defaults
11399                    .as_deref()
11400                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11401                serialized_completion.resolved = *resolved;
11402            }
11403            CompletionSource::BufferWord {
11404                word_range,
11405                resolved,
11406            } => {
11407                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11408                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11409                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11410                serialized_completion.resolved = *resolved;
11411            }
11412            CompletionSource::Custom => {
11413                serialized_completion.source = proto::completion::Source::Custom as i32;
11414                serialized_completion.resolved = true;
11415            }
11416            CompletionSource::Dap { sort_text } => {
11417                serialized_completion.source = proto::completion::Source::Dap as i32;
11418                serialized_completion.sort_text = Some(sort_text.clone());
11419            }
11420        }
11421
11422        serialized_completion
11423    }
11424
11425    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11426        let old_replace_start = completion
11427            .old_replace_start
11428            .and_then(deserialize_anchor)
11429            .context("invalid old start")?;
11430        let old_replace_end = completion
11431            .old_replace_end
11432            .and_then(deserialize_anchor)
11433            .context("invalid old end")?;
11434        let insert_range = {
11435            match completion.old_insert_start.zip(completion.old_insert_end) {
11436                Some((start, end)) => {
11437                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11438                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11439                    Some(start..end)
11440                }
11441                None => None,
11442            }
11443        };
11444        Ok(CoreCompletion {
11445            replace_range: old_replace_start..old_replace_end,
11446            new_text: completion.new_text,
11447            source: match proto::completion::Source::from_i32(completion.source) {
11448                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11449                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11450                    insert_range,
11451                    server_id: LanguageServerId::from_proto(completion.server_id),
11452                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11453                    lsp_defaults: completion
11454                        .lsp_defaults
11455                        .as_deref()
11456                        .map(serde_json::from_slice)
11457                        .transpose()?,
11458                    resolved: completion.resolved,
11459                },
11460                Some(proto::completion::Source::BufferWord) => {
11461                    let word_range = completion
11462                        .buffer_word_start
11463                        .and_then(deserialize_anchor)
11464                        .context("invalid buffer word start")?
11465                        ..completion
11466                            .buffer_word_end
11467                            .and_then(deserialize_anchor)
11468                            .context("invalid buffer word end")?;
11469                    CompletionSource::BufferWord {
11470                        word_range,
11471                        resolved: completion.resolved,
11472                    }
11473                }
11474                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11475                    sort_text: completion
11476                        .sort_text
11477                        .context("expected sort text to exist")?,
11478                },
11479                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11480            },
11481        })
11482    }
11483
11484    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11485        let (kind, lsp_action) = match &action.lsp_action {
11486            LspAction::Action(code_action) => (
11487                proto::code_action::Kind::Action as i32,
11488                serde_json::to_vec(code_action).unwrap(),
11489            ),
11490            LspAction::Command(command) => (
11491                proto::code_action::Kind::Command as i32,
11492                serde_json::to_vec(command).unwrap(),
11493            ),
11494            LspAction::CodeLens(code_lens) => (
11495                proto::code_action::Kind::CodeLens as i32,
11496                serde_json::to_vec(code_lens).unwrap(),
11497            ),
11498        };
11499
11500        proto::CodeAction {
11501            server_id: action.server_id.0 as u64,
11502            start: Some(serialize_anchor(&action.range.start)),
11503            end: Some(serialize_anchor(&action.range.end)),
11504            lsp_action,
11505            kind,
11506            resolved: action.resolved,
11507        }
11508    }
11509
11510    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11511        let start = action
11512            .start
11513            .and_then(deserialize_anchor)
11514            .context("invalid start")?;
11515        let end = action
11516            .end
11517            .and_then(deserialize_anchor)
11518            .context("invalid end")?;
11519        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11520            Some(proto::code_action::Kind::Action) => {
11521                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11522            }
11523            Some(proto::code_action::Kind::Command) => {
11524                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11525            }
11526            Some(proto::code_action::Kind::CodeLens) => {
11527                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11528            }
11529            None => anyhow::bail!("Unknown action kind {}", action.kind),
11530        };
11531        Ok(CodeAction {
11532            server_id: LanguageServerId(action.server_id as usize),
11533            range: start..end,
11534            resolved: action.resolved,
11535            lsp_action,
11536        })
11537    }
11538
11539    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11540        match &formatting_result {
11541            Ok(_) => self.last_formatting_failure = None,
11542            Err(error) => {
11543                let error_string = format!("{error:#}");
11544                log::error!("Formatting failed: {error_string}");
11545                self.last_formatting_failure
11546                    .replace(error_string.lines().join(" "));
11547            }
11548        }
11549    }
11550
11551    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11552        self.lsp_server_capabilities.remove(&for_server);
11553        for buffer_colors in self.lsp_document_colors.values_mut() {
11554            buffer_colors.colors.remove(&for_server);
11555            buffer_colors.cache_version += 1;
11556        }
11557        for buffer_lens in self.lsp_code_lens.values_mut() {
11558            buffer_lens.lens.remove(&for_server);
11559        }
11560        if let Some(local) = self.as_local_mut() {
11561            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11562            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11563                buffer_servers.remove(&for_server);
11564            }
11565        }
11566    }
11567
11568    pub fn result_id(
11569        &self,
11570        server_id: LanguageServerId,
11571        buffer_id: BufferId,
11572        cx: &App,
11573    ) -> Option<String> {
11574        let abs_path = self
11575            .buffer_store
11576            .read(cx)
11577            .get(buffer_id)
11578            .and_then(|b| File::from_dyn(b.read(cx).file()))
11579            .map(|f| f.abs_path(cx))?;
11580        self.as_local()?
11581            .buffer_pull_diagnostics_result_ids
11582            .get(&server_id)?
11583            .get(&abs_path)?
11584            .clone()
11585    }
11586
11587    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11588        let Some(local) = self.as_local() else {
11589            return HashMap::default();
11590        };
11591        local
11592            .buffer_pull_diagnostics_result_ids
11593            .get(&server_id)
11594            .into_iter()
11595            .flatten()
11596            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11597            .collect()
11598    }
11599
11600    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11601        if let Some(LanguageServerState::Running {
11602            workspace_refresh_task: Some(workspace_refresh_task),
11603            ..
11604        }) = self
11605            .as_local_mut()
11606            .and_then(|local| local.language_servers.get_mut(&server_id))
11607        {
11608            workspace_refresh_task.refresh_tx.try_send(()).ok();
11609        }
11610    }
11611
11612    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11613        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11614            return;
11615        };
11616        let Some(local) = self.as_local_mut() else {
11617            return;
11618        };
11619
11620        for server_id in buffer.update(cx, |buffer, cx| {
11621            local.language_server_ids_for_buffer(buffer, cx)
11622        }) {
11623            if let Some(LanguageServerState::Running {
11624                workspace_refresh_task: Some(workspace_refresh_task),
11625                ..
11626            }) = local.language_servers.get_mut(&server_id)
11627            {
11628                workspace_refresh_task.refresh_tx.try_send(()).ok();
11629            }
11630        }
11631    }
11632
11633    fn apply_workspace_diagnostic_report(
11634        &mut self,
11635        server_id: LanguageServerId,
11636        report: lsp::WorkspaceDiagnosticReportResult,
11637        cx: &mut Context<Self>,
11638    ) {
11639        let workspace_diagnostics =
11640            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11641        let mut unchanged_buffers = HashSet::default();
11642        let mut changed_buffers = HashSet::default();
11643        let workspace_diagnostics_updates = workspace_diagnostics
11644            .into_iter()
11645            .filter_map(
11646                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11647                    LspPullDiagnostics::Response {
11648                        server_id,
11649                        uri,
11650                        diagnostics,
11651                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11652                    LspPullDiagnostics::Default => None,
11653                },
11654            )
11655            .fold(
11656                HashMap::default(),
11657                |mut acc, (server_id, uri, diagnostics, version)| {
11658                    let (result_id, diagnostics) = match diagnostics {
11659                        PulledDiagnostics::Unchanged { result_id } => {
11660                            unchanged_buffers.insert(uri.clone());
11661                            (Some(result_id), Vec::new())
11662                        }
11663                        PulledDiagnostics::Changed {
11664                            result_id,
11665                            diagnostics,
11666                        } => {
11667                            changed_buffers.insert(uri.clone());
11668                            (result_id, diagnostics)
11669                        }
11670                    };
11671                    let disk_based_sources = Cow::Owned(
11672                        self.language_server_adapter_for_id(server_id)
11673                            .as_ref()
11674                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11675                            .unwrap_or(&[])
11676                            .to_vec(),
11677                    );
11678                    acc.entry(server_id)
11679                        .or_insert_with(Vec::new)
11680                        .push(DocumentDiagnosticsUpdate {
11681                            server_id,
11682                            diagnostics: lsp::PublishDiagnosticsParams {
11683                                uri,
11684                                diagnostics,
11685                                version,
11686                            },
11687                            result_id,
11688                            disk_based_sources,
11689                        });
11690                    acc
11691                },
11692            );
11693
11694        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11695            self.merge_lsp_diagnostics(
11696                DiagnosticSourceKind::Pulled,
11697                diagnostic_updates,
11698                |buffer, old_diagnostic, cx| {
11699                    File::from_dyn(buffer.file())
11700                        .and_then(|file| {
11701                            let abs_path = file.as_local()?.abs_path(cx);
11702                            lsp::Uri::from_file_path(abs_path).ok()
11703                        })
11704                        .is_none_or(|buffer_uri| {
11705                            unchanged_buffers.contains(&buffer_uri)
11706                                || match old_diagnostic.source_kind {
11707                                    DiagnosticSourceKind::Pulled => {
11708                                        !changed_buffers.contains(&buffer_uri)
11709                                    }
11710                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11711                                        true
11712                                    }
11713                                }
11714                        })
11715                },
11716                cx,
11717            )
11718            .log_err();
11719        }
11720    }
11721
11722    fn register_server_capabilities(
11723        &mut self,
11724        server_id: LanguageServerId,
11725        params: lsp::RegistrationParams,
11726        cx: &mut Context<Self>,
11727    ) -> anyhow::Result<()> {
11728        let server = self
11729            .language_server_for_id(server_id)
11730            .with_context(|| format!("no server {server_id} found"))?;
11731        for reg in params.registrations {
11732            match reg.method.as_str() {
11733                "workspace/didChangeWatchedFiles" => {
11734                    if let Some(options) = reg.register_options {
11735                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11736                            let caps = serde_json::from_value(options)?;
11737                            local_lsp_store
11738                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11739                            true
11740                        } else {
11741                            false
11742                        };
11743                        if notify {
11744                            notify_server_capabilities_updated(&server, cx);
11745                        }
11746                    }
11747                }
11748                "workspace/didChangeConfiguration" => {
11749                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11750                }
11751                "workspace/didChangeWorkspaceFolders" => {
11752                    // In this case register options is an empty object, we can ignore it
11753                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11754                        supported: Some(true),
11755                        change_notifications: Some(OneOf::Right(reg.id)),
11756                    };
11757                    server.update_capabilities(|capabilities| {
11758                        capabilities
11759                            .workspace
11760                            .get_or_insert_default()
11761                            .workspace_folders = Some(caps);
11762                    });
11763                    notify_server_capabilities_updated(&server, cx);
11764                }
11765                "workspace/symbol" => {
11766                    let options = parse_register_capabilities(reg)?;
11767                    server.update_capabilities(|capabilities| {
11768                        capabilities.workspace_symbol_provider = Some(options);
11769                    });
11770                    notify_server_capabilities_updated(&server, cx);
11771                }
11772                "workspace/fileOperations" => {
11773                    if let Some(options) = reg.register_options {
11774                        let caps = serde_json::from_value(options)?;
11775                        server.update_capabilities(|capabilities| {
11776                            capabilities
11777                                .workspace
11778                                .get_or_insert_default()
11779                                .file_operations = Some(caps);
11780                        });
11781                        notify_server_capabilities_updated(&server, cx);
11782                    }
11783                }
11784                "workspace/executeCommand" => {
11785                    if let Some(options) = reg.register_options {
11786                        let options = serde_json::from_value(options)?;
11787                        server.update_capabilities(|capabilities| {
11788                            capabilities.execute_command_provider = Some(options);
11789                        });
11790                        notify_server_capabilities_updated(&server, cx);
11791                    }
11792                }
11793                "textDocument/rangeFormatting" => {
11794                    let options = parse_register_capabilities(reg)?;
11795                    server.update_capabilities(|capabilities| {
11796                        capabilities.document_range_formatting_provider = Some(options);
11797                    });
11798                    notify_server_capabilities_updated(&server, cx);
11799                }
11800                "textDocument/onTypeFormatting" => {
11801                    if let Some(options) = reg
11802                        .register_options
11803                        .map(serde_json::from_value)
11804                        .transpose()?
11805                    {
11806                        server.update_capabilities(|capabilities| {
11807                            capabilities.document_on_type_formatting_provider = Some(options);
11808                        });
11809                        notify_server_capabilities_updated(&server, cx);
11810                    }
11811                }
11812                "textDocument/formatting" => {
11813                    let options = parse_register_capabilities(reg)?;
11814                    server.update_capabilities(|capabilities| {
11815                        capabilities.document_formatting_provider = Some(options);
11816                    });
11817                    notify_server_capabilities_updated(&server, cx);
11818                }
11819                "textDocument/rename" => {
11820                    let options = parse_register_capabilities(reg)?;
11821                    server.update_capabilities(|capabilities| {
11822                        capabilities.rename_provider = Some(options);
11823                    });
11824                    notify_server_capabilities_updated(&server, cx);
11825                }
11826                "textDocument/inlayHint" => {
11827                    let options = parse_register_capabilities(reg)?;
11828                    server.update_capabilities(|capabilities| {
11829                        capabilities.inlay_hint_provider = Some(options);
11830                    });
11831                    notify_server_capabilities_updated(&server, cx);
11832                }
11833                "textDocument/documentSymbol" => {
11834                    let options = parse_register_capabilities(reg)?;
11835                    server.update_capabilities(|capabilities| {
11836                        capabilities.document_symbol_provider = Some(options);
11837                    });
11838                    notify_server_capabilities_updated(&server, cx);
11839                }
11840                "textDocument/codeAction" => {
11841                    let options = parse_register_capabilities(reg)?;
11842                    let provider = match options {
11843                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11844                        OneOf::Right(caps) => caps,
11845                    };
11846                    server.update_capabilities(|capabilities| {
11847                        capabilities.code_action_provider = Some(provider);
11848                    });
11849                    notify_server_capabilities_updated(&server, cx);
11850                }
11851                "textDocument/definition" => {
11852                    let options = parse_register_capabilities(reg)?;
11853                    server.update_capabilities(|capabilities| {
11854                        capabilities.definition_provider = Some(options);
11855                    });
11856                    notify_server_capabilities_updated(&server, cx);
11857                }
11858                "textDocument/completion" => {
11859                    if let Some(caps) = reg
11860                        .register_options
11861                        .map(serde_json::from_value)
11862                        .transpose()?
11863                    {
11864                        server.update_capabilities(|capabilities| {
11865                            capabilities.completion_provider = Some(caps);
11866                        });
11867                        notify_server_capabilities_updated(&server, cx);
11868                    }
11869                }
11870                "textDocument/hover" => {
11871                    let options = parse_register_capabilities(reg)?;
11872                    let provider = match options {
11873                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11874                        OneOf::Right(caps) => caps,
11875                    };
11876                    server.update_capabilities(|capabilities| {
11877                        capabilities.hover_provider = Some(provider);
11878                    });
11879                    notify_server_capabilities_updated(&server, cx);
11880                }
11881                "textDocument/signatureHelp" => {
11882                    if let Some(caps) = reg
11883                        .register_options
11884                        .map(serde_json::from_value)
11885                        .transpose()?
11886                    {
11887                        server.update_capabilities(|capabilities| {
11888                            capabilities.signature_help_provider = Some(caps);
11889                        });
11890                        notify_server_capabilities_updated(&server, cx);
11891                    }
11892                }
11893                "textDocument/didChange" => {
11894                    if let Some(sync_kind) = reg
11895                        .register_options
11896                        .and_then(|opts| opts.get("syncKind").cloned())
11897                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11898                        .transpose()?
11899                    {
11900                        server.update_capabilities(|capabilities| {
11901                            let mut sync_options =
11902                                Self::take_text_document_sync_options(capabilities);
11903                            sync_options.change = Some(sync_kind);
11904                            capabilities.text_document_sync =
11905                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11906                        });
11907                        notify_server_capabilities_updated(&server, cx);
11908                    }
11909                }
11910                "textDocument/didSave" => {
11911                    if let Some(include_text) = reg
11912                        .register_options
11913                        .map(|opts| {
11914                            let transpose = opts
11915                                .get("includeText")
11916                                .cloned()
11917                                .map(serde_json::from_value::<Option<bool>>)
11918                                .transpose();
11919                            match transpose {
11920                                Ok(value) => Ok(value.flatten()),
11921                                Err(e) => Err(e),
11922                            }
11923                        })
11924                        .transpose()?
11925                    {
11926                        server.update_capabilities(|capabilities| {
11927                            let mut sync_options =
11928                                Self::take_text_document_sync_options(capabilities);
11929                            sync_options.save =
11930                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11931                                    include_text,
11932                                }));
11933                            capabilities.text_document_sync =
11934                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11935                        });
11936                        notify_server_capabilities_updated(&server, cx);
11937                    }
11938                }
11939                "textDocument/codeLens" => {
11940                    if let Some(caps) = reg
11941                        .register_options
11942                        .map(serde_json::from_value)
11943                        .transpose()?
11944                    {
11945                        server.update_capabilities(|capabilities| {
11946                            capabilities.code_lens_provider = Some(caps);
11947                        });
11948                        notify_server_capabilities_updated(&server, cx);
11949                    }
11950                }
11951                "textDocument/diagnostic" => {
11952                    if let Some(caps) = reg
11953                        .register_options
11954                        .map(serde_json::from_value)
11955                        .transpose()?
11956                    {
11957                        server.update_capabilities(|capabilities| {
11958                            capabilities.diagnostic_provider = Some(caps);
11959                        });
11960                        notify_server_capabilities_updated(&server, cx);
11961                    }
11962                }
11963                "textDocument/documentColor" => {
11964                    let options = parse_register_capabilities(reg)?;
11965                    let provider = match options {
11966                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11967                        OneOf::Right(caps) => caps,
11968                    };
11969                    server.update_capabilities(|capabilities| {
11970                        capabilities.color_provider = Some(provider);
11971                    });
11972                    notify_server_capabilities_updated(&server, cx);
11973                }
11974                _ => log::warn!("unhandled capability registration: {reg:?}"),
11975            }
11976        }
11977
11978        Ok(())
11979    }
11980
11981    fn unregister_server_capabilities(
11982        &mut self,
11983        server_id: LanguageServerId,
11984        params: lsp::UnregistrationParams,
11985        cx: &mut Context<Self>,
11986    ) -> anyhow::Result<()> {
11987        let server = self
11988            .language_server_for_id(server_id)
11989            .with_context(|| format!("no server {server_id} found"))?;
11990        for unreg in params.unregisterations.iter() {
11991            match unreg.method.as_str() {
11992                "workspace/didChangeWatchedFiles" => {
11993                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11994                        local_lsp_store
11995                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11996                        true
11997                    } else {
11998                        false
11999                    };
12000                    if notify {
12001                        notify_server_capabilities_updated(&server, cx);
12002                    }
12003                }
12004                "workspace/didChangeConfiguration" => {
12005                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12006                }
12007                "workspace/didChangeWorkspaceFolders" => {
12008                    server.update_capabilities(|capabilities| {
12009                        capabilities
12010                            .workspace
12011                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12012                                workspace_folders: None,
12013                                file_operations: None,
12014                            })
12015                            .workspace_folders = None;
12016                    });
12017                    notify_server_capabilities_updated(&server, cx);
12018                }
12019                "workspace/symbol" => {
12020                    server.update_capabilities(|capabilities| {
12021                        capabilities.workspace_symbol_provider = None
12022                    });
12023                    notify_server_capabilities_updated(&server, cx);
12024                }
12025                "workspace/fileOperations" => {
12026                    server.update_capabilities(|capabilities| {
12027                        capabilities
12028                            .workspace
12029                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12030                                workspace_folders: None,
12031                                file_operations: None,
12032                            })
12033                            .file_operations = None;
12034                    });
12035                    notify_server_capabilities_updated(&server, cx);
12036                }
12037                "workspace/executeCommand" => {
12038                    server.update_capabilities(|capabilities| {
12039                        capabilities.execute_command_provider = None;
12040                    });
12041                    notify_server_capabilities_updated(&server, cx);
12042                }
12043                "textDocument/rangeFormatting" => {
12044                    server.update_capabilities(|capabilities| {
12045                        capabilities.document_range_formatting_provider = None
12046                    });
12047                    notify_server_capabilities_updated(&server, cx);
12048                }
12049                "textDocument/onTypeFormatting" => {
12050                    server.update_capabilities(|capabilities| {
12051                        capabilities.document_on_type_formatting_provider = None;
12052                    });
12053                    notify_server_capabilities_updated(&server, cx);
12054                }
12055                "textDocument/formatting" => {
12056                    server.update_capabilities(|capabilities| {
12057                        capabilities.document_formatting_provider = None;
12058                    });
12059                    notify_server_capabilities_updated(&server, cx);
12060                }
12061                "textDocument/rename" => {
12062                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12063                    notify_server_capabilities_updated(&server, cx);
12064                }
12065                "textDocument/codeAction" => {
12066                    server.update_capabilities(|capabilities| {
12067                        capabilities.code_action_provider = None;
12068                    });
12069                    notify_server_capabilities_updated(&server, cx);
12070                }
12071                "textDocument/definition" => {
12072                    server.update_capabilities(|capabilities| {
12073                        capabilities.definition_provider = None;
12074                    });
12075                    notify_server_capabilities_updated(&server, cx);
12076                }
12077                "textDocument/completion" => {
12078                    server.update_capabilities(|capabilities| {
12079                        capabilities.completion_provider = None;
12080                    });
12081                    notify_server_capabilities_updated(&server, cx);
12082                }
12083                "textDocument/hover" => {
12084                    server.update_capabilities(|capabilities| {
12085                        capabilities.hover_provider = None;
12086                    });
12087                    notify_server_capabilities_updated(&server, cx);
12088                }
12089                "textDocument/signatureHelp" => {
12090                    server.update_capabilities(|capabilities| {
12091                        capabilities.signature_help_provider = None;
12092                    });
12093                    notify_server_capabilities_updated(&server, cx);
12094                }
12095                "textDocument/didChange" => {
12096                    server.update_capabilities(|capabilities| {
12097                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12098                        sync_options.change = None;
12099                        capabilities.text_document_sync =
12100                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12101                    });
12102                    notify_server_capabilities_updated(&server, cx);
12103                }
12104                "textDocument/didSave" => {
12105                    server.update_capabilities(|capabilities| {
12106                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12107                        sync_options.save = None;
12108                        capabilities.text_document_sync =
12109                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12110                    });
12111                    notify_server_capabilities_updated(&server, cx);
12112                }
12113                "textDocument/codeLens" => {
12114                    server.update_capabilities(|capabilities| {
12115                        capabilities.code_lens_provider = None;
12116                    });
12117                    notify_server_capabilities_updated(&server, cx);
12118                }
12119                "textDocument/diagnostic" => {
12120                    server.update_capabilities(|capabilities| {
12121                        capabilities.diagnostic_provider = None;
12122                    });
12123                    notify_server_capabilities_updated(&server, cx);
12124                }
12125                "textDocument/documentColor" => {
12126                    server.update_capabilities(|capabilities| {
12127                        capabilities.color_provider = None;
12128                    });
12129                    notify_server_capabilities_updated(&server, cx);
12130                }
12131                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12132            }
12133        }
12134
12135        Ok(())
12136    }
12137
12138    async fn query_lsp_locally<T>(
12139        lsp_store: Entity<Self>,
12140        sender_id: proto::PeerId,
12141        lsp_request_id: LspRequestId,
12142        proto_request: T::ProtoRequest,
12143        position: Option<Anchor>,
12144        mut cx: AsyncApp,
12145    ) -> Result<()>
12146    where
12147        T: LspCommand + Clone,
12148        T::ProtoRequest: proto::LspRequestMessage,
12149        <T::ProtoRequest as proto::RequestMessage>::Response:
12150            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12151    {
12152        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12153        let version = deserialize_version(proto_request.buffer_version());
12154        let buffer = lsp_store.update(&mut cx, |this, cx| {
12155            this.buffer_store.read(cx).get_existing(buffer_id)
12156        })??;
12157        buffer
12158            .update(&mut cx, |buffer, _| {
12159                buffer.wait_for_version(version.clone())
12160            })?
12161            .await?;
12162        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
12163        let request =
12164            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12165        lsp_store.update(&mut cx, |lsp_store, cx| {
12166            let request_task =
12167                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
12168            let existing_queries = lsp_store
12169                .running_lsp_requests
12170                .entry(TypeId::of::<T>())
12171                .or_default();
12172            if T::ProtoRequest::stop_previous_requests()
12173                || buffer_version.changed_since(&existing_queries.0)
12174            {
12175                existing_queries.1.clear();
12176            }
12177            existing_queries.1.insert(
12178                lsp_request_id,
12179                cx.spawn(async move |lsp_store, cx| {
12180                    let response = request_task.await;
12181                    lsp_store
12182                        .update(cx, |lsp_store, cx| {
12183                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12184                            {
12185                                let response = response
12186                                    .into_iter()
12187                                    .map(|(server_id, response)| {
12188                                        (
12189                                            server_id.to_proto(),
12190                                            T::response_to_proto(
12191                                                response,
12192                                                lsp_store,
12193                                                sender_id,
12194                                                &buffer_version,
12195                                                cx,
12196                                            )
12197                                            .into(),
12198                                        )
12199                                    })
12200                                    .collect::<HashMap<_, _>>();
12201                                match client.send_lsp_response::<T::ProtoRequest>(
12202                                    project_id,
12203                                    lsp_request_id,
12204                                    response,
12205                                ) {
12206                                    Ok(()) => {}
12207                                    Err(e) => {
12208                                        log::error!("Failed to send LSP response: {e:#}",)
12209                                    }
12210                                }
12211                            }
12212                        })
12213                        .ok();
12214                }),
12215            );
12216        })?;
12217        Ok(())
12218    }
12219
12220    fn take_text_document_sync_options(
12221        capabilities: &mut lsp::ServerCapabilities,
12222    ) -> lsp::TextDocumentSyncOptions {
12223        match capabilities.text_document_sync.take() {
12224            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12225            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12226                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12227                sync_options.change = Some(sync_kind);
12228                sync_options
12229            }
12230            None => lsp::TextDocumentSyncOptions::default(),
12231        }
12232    }
12233
12234    #[cfg(any(test, feature = "test-support"))]
12235    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12236        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
12237        Some(data.update.take()?.1)
12238    }
12239
12240    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12241        self.downstream_client.clone()
12242    }
12243
12244    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12245        self.worktree_store.clone()
12246    }
12247}
12248
12249// Registration with registerOptions as null, should fallback to true.
12250// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12251fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12252    reg: lsp::Registration,
12253) -> Result<OneOf<bool, T>> {
12254    Ok(match reg.register_options {
12255        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12256        None => OneOf::Left(true),
12257    })
12258}
12259
12260fn subscribe_to_binary_statuses(
12261    languages: &Arc<LanguageRegistry>,
12262    cx: &mut Context<'_, LspStore>,
12263) -> Task<()> {
12264    let mut server_statuses = languages.language_server_binary_statuses();
12265    cx.spawn(async move |lsp_store, cx| {
12266        while let Some((server_name, binary_status)) = server_statuses.next().await {
12267            if lsp_store
12268                .update(cx, |_, cx| {
12269                    let mut message = None;
12270                    let binary_status = match binary_status {
12271                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12272                        BinaryStatus::CheckingForUpdate => {
12273                            proto::ServerBinaryStatus::CheckingForUpdate
12274                        }
12275                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12276                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12277                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12278                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12279                        BinaryStatus::Failed { error } => {
12280                            message = Some(error);
12281                            proto::ServerBinaryStatus::Failed
12282                        }
12283                    };
12284                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12285                        // Binary updates are about the binary that might not have any language server id at that point.
12286                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12287                        language_server_id: LanguageServerId(0),
12288                        name: Some(server_name),
12289                        message: proto::update_language_server::Variant::StatusUpdate(
12290                            proto::StatusUpdate {
12291                                message,
12292                                status: Some(proto::status_update::Status::Binary(
12293                                    binary_status as i32,
12294                                )),
12295                            },
12296                        ),
12297                    });
12298                })
12299                .is_err()
12300            {
12301                break;
12302            }
12303        }
12304    })
12305}
12306
12307fn lsp_workspace_diagnostics_refresh(
12308    server: Arc<LanguageServer>,
12309    cx: &mut Context<'_, LspStore>,
12310) -> Option<WorkspaceRefreshTask> {
12311    let identifier = match server.capabilities().diagnostic_provider? {
12312        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12313            if !diagnostic_options.workspace_diagnostics {
12314                return None;
12315            }
12316            diagnostic_options.identifier
12317        }
12318        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12319            let diagnostic_options = registration_options.diagnostic_options;
12320            if !diagnostic_options.workspace_diagnostics {
12321                return None;
12322            }
12323            diagnostic_options.identifier
12324        }
12325    };
12326
12327    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12328    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12329    refresh_tx.try_send(()).ok();
12330
12331    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12332        let mut attempts = 0;
12333        let max_attempts = 50;
12334        let mut requests = 0;
12335
12336        loop {
12337            let Some(()) = refresh_rx.recv().await else {
12338                return;
12339            };
12340
12341            'request: loop {
12342                requests += 1;
12343                if attempts > max_attempts {
12344                    log::error!(
12345                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12346                    );
12347                    return;
12348                }
12349                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12350                cx.background_executor()
12351                    .timer(Duration::from_millis(backoff_millis))
12352                    .await;
12353                attempts += 1;
12354
12355                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12356                    lsp_store
12357                        .all_result_ids(server.server_id())
12358                        .into_iter()
12359                        .filter_map(|(abs_path, result_id)| {
12360                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12361                            Some(lsp::PreviousResultId {
12362                                uri,
12363                                value: result_id,
12364                            })
12365                        })
12366                        .collect()
12367                }) else {
12368                    return;
12369                };
12370
12371                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12372
12373                progress_rx.try_recv().ok();
12374                let timer =
12375                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12376                let progress = pin!(progress_rx.recv().fuse());
12377                let response_result = server
12378                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12379                        lsp::WorkspaceDiagnosticParams {
12380                            previous_result_ids,
12381                            identifier: identifier.clone(),
12382                            work_done_progress_params: Default::default(),
12383                            partial_result_params: lsp::PartialResultParams {
12384                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12385                            },
12386                        },
12387                        select(timer, progress).then(|either| match either {
12388                            Either::Left((message, ..)) => ready(message).left_future(),
12389                            Either::Right(..) => pending::<String>().right_future(),
12390                        }),
12391                    )
12392                    .await;
12393
12394                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12395                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12396                match response_result {
12397                    ConnectionResult::Timeout => {
12398                        log::error!("Timeout during workspace diagnostics pull");
12399                        continue 'request;
12400                    }
12401                    ConnectionResult::ConnectionReset => {
12402                        log::error!("Server closed a workspace diagnostics pull request");
12403                        continue 'request;
12404                    }
12405                    ConnectionResult::Result(Err(e)) => {
12406                        log::error!("Error during workspace diagnostics pull: {e:#}");
12407                        break 'request;
12408                    }
12409                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12410                        attempts = 0;
12411                        if lsp_store
12412                            .update(cx, |lsp_store, cx| {
12413                                lsp_store.apply_workspace_diagnostic_report(
12414                                    server.server_id(),
12415                                    pulled_diagnostics,
12416                                    cx,
12417                                )
12418                            })
12419                            .is_err()
12420                        {
12421                            return;
12422                        }
12423                        break 'request;
12424                    }
12425                }
12426            }
12427        }
12428    });
12429
12430    Some(WorkspaceRefreshTask {
12431        refresh_tx,
12432        progress_tx,
12433        task: workspace_query_language_server,
12434    })
12435}
12436
12437fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12438    let CompletionSource::BufferWord {
12439        word_range,
12440        resolved,
12441    } = &mut completion.source
12442    else {
12443        return;
12444    };
12445    if *resolved {
12446        return;
12447    }
12448
12449    if completion.new_text
12450        != snapshot
12451            .text_for_range(word_range.clone())
12452            .collect::<String>()
12453    {
12454        return;
12455    }
12456
12457    let mut offset = 0;
12458    for chunk in snapshot.chunks(word_range.clone(), true) {
12459        let end_offset = offset + chunk.text.len();
12460        if let Some(highlight_id) = chunk.syntax_highlight_id {
12461            completion
12462                .label
12463                .runs
12464                .push((offset..end_offset, highlight_id));
12465        }
12466        offset = end_offset;
12467    }
12468    *resolved = true;
12469}
12470
12471impl EventEmitter<LspStoreEvent> for LspStore {}
12472
12473fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12474    hover
12475        .contents
12476        .retain(|hover_block| !hover_block.text.trim().is_empty());
12477    if hover.contents.is_empty() {
12478        None
12479    } else {
12480        Some(hover)
12481    }
12482}
12483
12484async fn populate_labels_for_completions(
12485    new_completions: Vec<CoreCompletion>,
12486    language: Option<Arc<Language>>,
12487    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12488) -> Vec<Completion> {
12489    let lsp_completions = new_completions
12490        .iter()
12491        .filter_map(|new_completion| {
12492            new_completion
12493                .source
12494                .lsp_completion(true)
12495                .map(|lsp_completion| lsp_completion.into_owned())
12496        })
12497        .collect::<Vec<_>>();
12498
12499    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12500        lsp_adapter
12501            .labels_for_completions(&lsp_completions, language)
12502            .await
12503            .log_err()
12504            .unwrap_or_default()
12505    } else {
12506        Vec::new()
12507    }
12508    .into_iter()
12509    .fuse();
12510
12511    let mut completions = Vec::new();
12512    for completion in new_completions {
12513        match completion.source.lsp_completion(true) {
12514            Some(lsp_completion) => {
12515                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12516
12517                let mut label = labels.next().flatten().unwrap_or_else(|| {
12518                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12519                });
12520                ensure_uniform_list_compatible_label(&mut label);
12521                completions.push(Completion {
12522                    label,
12523                    documentation,
12524                    replace_range: completion.replace_range,
12525                    new_text: completion.new_text,
12526                    insert_text_mode: lsp_completion.insert_text_mode,
12527                    source: completion.source,
12528                    icon_path: None,
12529                    confirm: None,
12530                });
12531            }
12532            None => {
12533                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12534                ensure_uniform_list_compatible_label(&mut label);
12535                completions.push(Completion {
12536                    label,
12537                    documentation: None,
12538                    replace_range: completion.replace_range,
12539                    new_text: completion.new_text,
12540                    source: completion.source,
12541                    insert_text_mode: None,
12542                    icon_path: None,
12543                    confirm: None,
12544                });
12545            }
12546        }
12547    }
12548    completions
12549}
12550
12551#[derive(Debug)]
12552pub enum LanguageServerToQuery {
12553    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12554    FirstCapable,
12555    /// Query a specific language server.
12556    Other(LanguageServerId),
12557}
12558
12559#[derive(Default)]
12560struct RenamePathsWatchedForServer {
12561    did_rename: Vec<RenameActionPredicate>,
12562    will_rename: Vec<RenameActionPredicate>,
12563}
12564
12565impl RenamePathsWatchedForServer {
12566    fn with_did_rename_patterns(
12567        mut self,
12568        did_rename: Option<&FileOperationRegistrationOptions>,
12569    ) -> Self {
12570        if let Some(did_rename) = did_rename {
12571            self.did_rename = did_rename
12572                .filters
12573                .iter()
12574                .filter_map(|filter| filter.try_into().log_err())
12575                .collect();
12576        }
12577        self
12578    }
12579    fn with_will_rename_patterns(
12580        mut self,
12581        will_rename: Option<&FileOperationRegistrationOptions>,
12582    ) -> Self {
12583        if let Some(will_rename) = will_rename {
12584            self.will_rename = will_rename
12585                .filters
12586                .iter()
12587                .filter_map(|filter| filter.try_into().log_err())
12588                .collect();
12589        }
12590        self
12591    }
12592
12593    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12594        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12595    }
12596    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12597        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12598    }
12599}
12600
12601impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12602    type Error = globset::Error;
12603    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12604        Ok(Self {
12605            kind: ops.pattern.matches.clone(),
12606            glob: GlobBuilder::new(&ops.pattern.glob)
12607                .case_insensitive(
12608                    ops.pattern
12609                        .options
12610                        .as_ref()
12611                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12612                )
12613                .build()?
12614                .compile_matcher(),
12615        })
12616    }
12617}
12618struct RenameActionPredicate {
12619    glob: GlobMatcher,
12620    kind: Option<FileOperationPatternKind>,
12621}
12622
12623impl RenameActionPredicate {
12624    // Returns true if language server should be notified
12625    fn eval(&self, path: &str, is_dir: bool) -> bool {
12626        self.kind.as_ref().is_none_or(|kind| {
12627            let expected_kind = if is_dir {
12628                FileOperationPatternKind::Folder
12629            } else {
12630                FileOperationPatternKind::File
12631            };
12632            kind == &expected_kind
12633        }) && self.glob.is_match(path)
12634    }
12635}
12636
12637#[derive(Default)]
12638struct LanguageServerWatchedPaths {
12639    worktree_paths: HashMap<WorktreeId, GlobSet>,
12640    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12641}
12642
12643#[derive(Default)]
12644struct LanguageServerWatchedPathsBuilder {
12645    worktree_paths: HashMap<WorktreeId, GlobSet>,
12646    abs_paths: HashMap<Arc<Path>, GlobSet>,
12647}
12648
12649impl LanguageServerWatchedPathsBuilder {
12650    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12651        self.worktree_paths.insert(worktree_id, glob_set);
12652    }
12653    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12654        self.abs_paths.insert(path, glob_set);
12655    }
12656    fn build(
12657        self,
12658        fs: Arc<dyn Fs>,
12659        language_server_id: LanguageServerId,
12660        cx: &mut Context<LspStore>,
12661    ) -> LanguageServerWatchedPaths {
12662        let project = cx.weak_entity();
12663
12664        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12665        let abs_paths = self
12666            .abs_paths
12667            .into_iter()
12668            .map(|(abs_path, globset)| {
12669                let task = cx.spawn({
12670                    let abs_path = abs_path.clone();
12671                    let fs = fs.clone();
12672
12673                    let lsp_store = project.clone();
12674                    async move |_, cx| {
12675                        maybe!(async move {
12676                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12677                            while let Some(update) = push_updates.0.next().await {
12678                                let action = lsp_store
12679                                    .update(cx, |this, _| {
12680                                        let Some(local) = this.as_local() else {
12681                                            return ControlFlow::Break(());
12682                                        };
12683                                        let Some(watcher) = local
12684                                            .language_server_watched_paths
12685                                            .get(&language_server_id)
12686                                        else {
12687                                            return ControlFlow::Break(());
12688                                        };
12689                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12690                                            "Watched abs path is not registered with a watcher",
12691                                        );
12692                                        let matching_entries = update
12693                                            .into_iter()
12694                                            .filter(|event| globs.is_match(&event.path))
12695                                            .collect::<Vec<_>>();
12696                                        this.lsp_notify_abs_paths_changed(
12697                                            language_server_id,
12698                                            matching_entries,
12699                                        );
12700                                        ControlFlow::Continue(())
12701                                    })
12702                                    .ok()?;
12703
12704                                if action.is_break() {
12705                                    break;
12706                                }
12707                            }
12708                            Some(())
12709                        })
12710                        .await;
12711                    }
12712                });
12713                (abs_path, (globset, task))
12714            })
12715            .collect();
12716        LanguageServerWatchedPaths {
12717            worktree_paths: self.worktree_paths,
12718            abs_paths,
12719        }
12720    }
12721}
12722
12723struct LspBufferSnapshot {
12724    version: i32,
12725    snapshot: TextBufferSnapshot,
12726}
12727
12728/// A prompt requested by LSP server.
12729#[derive(Clone, Debug)]
12730pub struct LanguageServerPromptRequest {
12731    pub level: PromptLevel,
12732    pub message: String,
12733    pub actions: Vec<MessageActionItem>,
12734    pub lsp_name: String,
12735    pub(crate) response_channel: Sender<MessageActionItem>,
12736}
12737
12738impl LanguageServerPromptRequest {
12739    pub async fn respond(self, index: usize) -> Option<()> {
12740        if let Some(response) = self.actions.into_iter().nth(index) {
12741            self.response_channel.send(response).await.ok()
12742        } else {
12743            None
12744        }
12745    }
12746}
12747impl PartialEq for LanguageServerPromptRequest {
12748    fn eq(&self, other: &Self) -> bool {
12749        self.message == other.message && self.actions == other.actions
12750    }
12751}
12752
12753#[derive(Clone, Debug, PartialEq)]
12754pub enum LanguageServerLogType {
12755    Log(MessageType),
12756    Trace { verbose_info: Option<String> },
12757    Rpc { received: bool },
12758}
12759
12760impl LanguageServerLogType {
12761    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12762        match self {
12763            Self::Log(log_type) => {
12764                use proto::log_message::LogLevel;
12765                let level = match *log_type {
12766                    MessageType::ERROR => LogLevel::Error,
12767                    MessageType::WARNING => LogLevel::Warning,
12768                    MessageType::INFO => LogLevel::Info,
12769                    MessageType::LOG => LogLevel::Log,
12770                    other => {
12771                        log::warn!("Unknown lsp log message type: {other:?}");
12772                        LogLevel::Log
12773                    }
12774                };
12775                proto::language_server_log::LogType::Log(proto::LogMessage {
12776                    level: level as i32,
12777                })
12778            }
12779            Self::Trace { verbose_info } => {
12780                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12781                    verbose_info: verbose_info.to_owned(),
12782                })
12783            }
12784            Self::Rpc { received } => {
12785                let kind = if *received {
12786                    proto::rpc_message::Kind::Received
12787                } else {
12788                    proto::rpc_message::Kind::Sent
12789                };
12790                let kind = kind as i32;
12791                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12792            }
12793        }
12794    }
12795
12796    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12797        use proto::log_message::LogLevel;
12798        use proto::rpc_message;
12799        match log_type {
12800            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12801                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12802                    LogLevel::Error => MessageType::ERROR,
12803                    LogLevel::Warning => MessageType::WARNING,
12804                    LogLevel::Info => MessageType::INFO,
12805                    LogLevel::Log => MessageType::LOG,
12806                },
12807            ),
12808            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12809                verbose_info: trace_message.verbose_info,
12810            },
12811            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12812                received: match rpc_message::Kind::from_i32(message.kind)
12813                    .unwrap_or(rpc_message::Kind::Received)
12814                {
12815                    rpc_message::Kind::Received => true,
12816                    rpc_message::Kind::Sent => false,
12817                },
12818            },
12819        }
12820    }
12821}
12822
12823pub struct WorkspaceRefreshTask {
12824    refresh_tx: mpsc::Sender<()>,
12825    progress_tx: mpsc::Sender<()>,
12826    #[allow(dead_code)]
12827    task: Task<()>,
12828}
12829
12830pub enum LanguageServerState {
12831    Starting {
12832        startup: Task<Option<Arc<LanguageServer>>>,
12833        /// List of language servers that will be added to the workspace once it's initialization completes.
12834        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12835    },
12836
12837    Running {
12838        adapter: Arc<CachedLspAdapter>,
12839        server: Arc<LanguageServer>,
12840        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12841        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12842    },
12843}
12844
12845impl LanguageServerState {
12846    fn add_workspace_folder(&self, uri: Uri) {
12847        match self {
12848            LanguageServerState::Starting {
12849                pending_workspace_folders,
12850                ..
12851            } => {
12852                pending_workspace_folders.lock().insert(uri);
12853            }
12854            LanguageServerState::Running { server, .. } => {
12855                server.add_workspace_folder(uri);
12856            }
12857        }
12858    }
12859    fn _remove_workspace_folder(&self, uri: Uri) {
12860        match self {
12861            LanguageServerState::Starting {
12862                pending_workspace_folders,
12863                ..
12864            } => {
12865                pending_workspace_folders.lock().remove(&uri);
12866            }
12867            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12868        }
12869    }
12870}
12871
12872impl std::fmt::Debug for LanguageServerState {
12873    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12874        match self {
12875            LanguageServerState::Starting { .. } => {
12876                f.debug_struct("LanguageServerState::Starting").finish()
12877            }
12878            LanguageServerState::Running { .. } => {
12879                f.debug_struct("LanguageServerState::Running").finish()
12880            }
12881        }
12882    }
12883}
12884
12885#[derive(Clone, Debug, Serialize)]
12886pub struct LanguageServerProgress {
12887    pub is_disk_based_diagnostics_progress: bool,
12888    pub is_cancellable: bool,
12889    pub title: Option<String>,
12890    pub message: Option<String>,
12891    pub percentage: Option<usize>,
12892    #[serde(skip_serializing)]
12893    pub last_update_at: Instant,
12894}
12895
12896#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12897pub struct DiagnosticSummary {
12898    pub error_count: usize,
12899    pub warning_count: usize,
12900}
12901
12902impl DiagnosticSummary {
12903    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12904        let mut this = Self {
12905            error_count: 0,
12906            warning_count: 0,
12907        };
12908
12909        for entry in diagnostics {
12910            if entry.diagnostic.is_primary {
12911                match entry.diagnostic.severity {
12912                    DiagnosticSeverity::ERROR => this.error_count += 1,
12913                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12914                    _ => {}
12915                }
12916            }
12917        }
12918
12919        this
12920    }
12921
12922    pub fn is_empty(&self) -> bool {
12923        self.error_count == 0 && self.warning_count == 0
12924    }
12925
12926    pub fn to_proto(
12927        self,
12928        language_server_id: LanguageServerId,
12929        path: &Path,
12930    ) -> proto::DiagnosticSummary {
12931        proto::DiagnosticSummary {
12932            path: path.to_proto(),
12933            language_server_id: language_server_id.0 as u64,
12934            error_count: self.error_count as u32,
12935            warning_count: self.warning_count as u32,
12936        }
12937    }
12938}
12939
12940#[derive(Clone, Debug)]
12941pub enum CompletionDocumentation {
12942    /// There is no documentation for this completion.
12943    Undocumented,
12944    /// A single line of documentation.
12945    SingleLine(SharedString),
12946    /// Multiple lines of plain text documentation.
12947    MultiLinePlainText(SharedString),
12948    /// Markdown documentation.
12949    MultiLineMarkdown(SharedString),
12950    /// Both single line and multiple lines of plain text documentation.
12951    SingleLineAndMultiLinePlainText {
12952        single_line: SharedString,
12953        plain_text: Option<SharedString>,
12954    },
12955}
12956
12957impl CompletionDocumentation {
12958    #[cfg(any(test, feature = "test-support"))]
12959    pub fn text(&self) -> SharedString {
12960        match self {
12961            CompletionDocumentation::Undocumented => "".into(),
12962            CompletionDocumentation::SingleLine(s) => s.clone(),
12963            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12964            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12965            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12966                single_line.clone()
12967            }
12968        }
12969    }
12970}
12971
12972impl From<lsp::Documentation> for CompletionDocumentation {
12973    fn from(docs: lsp::Documentation) -> Self {
12974        match docs {
12975            lsp::Documentation::String(text) => {
12976                if text.lines().count() <= 1 {
12977                    CompletionDocumentation::SingleLine(text.into())
12978                } else {
12979                    CompletionDocumentation::MultiLinePlainText(text.into())
12980                }
12981            }
12982
12983            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12984                lsp::MarkupKind::PlainText => {
12985                    if value.lines().count() <= 1 {
12986                        CompletionDocumentation::SingleLine(value.into())
12987                    } else {
12988                        CompletionDocumentation::MultiLinePlainText(value.into())
12989                    }
12990                }
12991
12992                lsp::MarkupKind::Markdown => {
12993                    CompletionDocumentation::MultiLineMarkdown(value.into())
12994                }
12995            },
12996        }
12997    }
12998}
12999
13000fn glob_literal_prefix(glob: &Path) -> PathBuf {
13001    glob.components()
13002        .take_while(|component| match component {
13003            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13004            _ => true,
13005        })
13006        .collect()
13007}
13008
13009pub struct SshLspAdapter {
13010    name: LanguageServerName,
13011    binary: LanguageServerBinary,
13012    initialization_options: Option<String>,
13013    code_action_kinds: Option<Vec<CodeActionKind>>,
13014}
13015
13016impl SshLspAdapter {
13017    pub fn new(
13018        name: LanguageServerName,
13019        binary: LanguageServerBinary,
13020        initialization_options: Option<String>,
13021        code_action_kinds: Option<String>,
13022    ) -> Self {
13023        Self {
13024            name,
13025            binary,
13026            initialization_options,
13027            code_action_kinds: code_action_kinds
13028                .as_ref()
13029                .and_then(|c| serde_json::from_str(c).ok()),
13030        }
13031    }
13032}
13033
13034#[async_trait(?Send)]
13035impl LspAdapter for SshLspAdapter {
13036    fn name(&self) -> LanguageServerName {
13037        self.name.clone()
13038    }
13039
13040    async fn initialization_options(
13041        self: Arc<Self>,
13042        _: &dyn Fs,
13043        _: &Arc<dyn LspAdapterDelegate>,
13044    ) -> Result<Option<serde_json::Value>> {
13045        let Some(options) = &self.initialization_options else {
13046            return Ok(None);
13047        };
13048        let result = serde_json::from_str(options)?;
13049        Ok(result)
13050    }
13051
13052    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13053        self.code_action_kinds.clone()
13054    }
13055
13056    async fn check_if_user_installed(
13057        &self,
13058        _: &dyn LspAdapterDelegate,
13059        _: Option<Toolchain>,
13060        _: &AsyncApp,
13061    ) -> Option<LanguageServerBinary> {
13062        Some(self.binary.clone())
13063    }
13064
13065    async fn cached_server_binary(
13066        &self,
13067        _: PathBuf,
13068        _: &dyn LspAdapterDelegate,
13069    ) -> Option<LanguageServerBinary> {
13070        None
13071    }
13072
13073    async fn fetch_latest_server_version(
13074        &self,
13075        _: &dyn LspAdapterDelegate,
13076    ) -> Result<Box<dyn 'static + Send + Any>> {
13077        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13078    }
13079
13080    async fn fetch_server_binary(
13081        &self,
13082        _: Box<dyn 'static + Send + Any>,
13083        _: PathBuf,
13084        _: &dyn LspAdapterDelegate,
13085    ) -> Result<LanguageServerBinary> {
13086        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13087    }
13088}
13089
13090pub fn language_server_settings<'a>(
13091    delegate: &'a dyn LspAdapterDelegate,
13092    language: &LanguageServerName,
13093    cx: &'a App,
13094) -> Option<&'a LspSettings> {
13095    language_server_settings_for(
13096        SettingsLocation {
13097            worktree_id: delegate.worktree_id(),
13098            path: delegate.worktree_root_path(),
13099        },
13100        language,
13101        cx,
13102    )
13103}
13104
13105pub(crate) fn language_server_settings_for<'a>(
13106    location: SettingsLocation<'a>,
13107    language: &LanguageServerName,
13108    cx: &'a App,
13109) -> Option<&'a LspSettings> {
13110    ProjectSettings::get(Some(location), cx).lsp.get(language)
13111}
13112
13113pub struct LocalLspAdapterDelegate {
13114    lsp_store: WeakEntity<LspStore>,
13115    worktree: worktree::Snapshot,
13116    fs: Arc<dyn Fs>,
13117    http_client: Arc<dyn HttpClient>,
13118    language_registry: Arc<LanguageRegistry>,
13119    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13120}
13121
13122impl LocalLspAdapterDelegate {
13123    pub fn new(
13124        language_registry: Arc<LanguageRegistry>,
13125        environment: &Entity<ProjectEnvironment>,
13126        lsp_store: WeakEntity<LspStore>,
13127        worktree: &Entity<Worktree>,
13128        http_client: Arc<dyn HttpClient>,
13129        fs: Arc<dyn Fs>,
13130        cx: &mut App,
13131    ) -> Arc<Self> {
13132        let load_shell_env_task = environment.update(cx, |env, cx| {
13133            env.get_worktree_environment(worktree.clone(), cx)
13134        });
13135
13136        Arc::new(Self {
13137            lsp_store,
13138            worktree: worktree.read(cx).snapshot(),
13139            fs,
13140            http_client,
13141            language_registry,
13142            load_shell_env_task,
13143        })
13144    }
13145
13146    fn from_local_lsp(
13147        local: &LocalLspStore,
13148        worktree: &Entity<Worktree>,
13149        cx: &mut App,
13150    ) -> Arc<Self> {
13151        Self::new(
13152            local.languages.clone(),
13153            &local.environment,
13154            local.weak.clone(),
13155            worktree,
13156            local.http_client.clone(),
13157            local.fs.clone(),
13158            cx,
13159        )
13160    }
13161}
13162
13163#[async_trait]
13164impl LspAdapterDelegate for LocalLspAdapterDelegate {
13165    fn show_notification(&self, message: &str, cx: &mut App) {
13166        self.lsp_store
13167            .update(cx, |_, cx| {
13168                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13169            })
13170            .ok();
13171    }
13172
13173    fn http_client(&self) -> Arc<dyn HttpClient> {
13174        self.http_client.clone()
13175    }
13176
13177    fn worktree_id(&self) -> WorktreeId {
13178        self.worktree.id()
13179    }
13180
13181    fn worktree_root_path(&self) -> &Path {
13182        self.worktree.abs_path().as_ref()
13183    }
13184
13185    async fn shell_env(&self) -> HashMap<String, String> {
13186        let task = self.load_shell_env_task.clone();
13187        task.await.unwrap_or_default()
13188    }
13189
13190    async fn npm_package_installed_version(
13191        &self,
13192        package_name: &str,
13193    ) -> Result<Option<(PathBuf, String)>> {
13194        let local_package_directory = self.worktree_root_path();
13195        let node_modules_directory = local_package_directory.join("node_modules");
13196
13197        if let Some(version) =
13198            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13199        {
13200            return Ok(Some((node_modules_directory, version)));
13201        }
13202        let Some(npm) = self.which("npm".as_ref()).await else {
13203            log::warn!(
13204                "Failed to find npm executable for {:?}",
13205                local_package_directory
13206            );
13207            return Ok(None);
13208        };
13209
13210        let env = self.shell_env().await;
13211        let output = util::command::new_smol_command(&npm)
13212            .args(["root", "-g"])
13213            .envs(env)
13214            .current_dir(local_package_directory)
13215            .output()
13216            .await?;
13217        let global_node_modules =
13218            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13219
13220        if let Some(version) =
13221            read_package_installed_version(global_node_modules.clone(), package_name).await?
13222        {
13223            return Ok(Some((global_node_modules, version)));
13224        }
13225        return Ok(None);
13226    }
13227
13228    #[cfg(not(target_os = "windows"))]
13229    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13230        let worktree_abs_path = self.worktree.abs_path();
13231        let shell_path = self.shell_env().await.get("PATH").cloned();
13232        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13233    }
13234
13235    #[cfg(target_os = "windows")]
13236    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13237        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
13238        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
13239        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
13240        which::which(command).ok()
13241    }
13242
13243    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13244        let working_dir = self.worktree_root_path();
13245        let output = util::command::new_smol_command(&command.path)
13246            .args(command.arguments)
13247            .envs(command.env.clone().unwrap_or_default())
13248            .current_dir(working_dir)
13249            .output()
13250            .await?;
13251
13252        anyhow::ensure!(
13253            output.status.success(),
13254            "{}, stdout: {:?}, stderr: {:?}",
13255            output.status,
13256            String::from_utf8_lossy(&output.stdout),
13257            String::from_utf8_lossy(&output.stderr)
13258        );
13259        Ok(())
13260    }
13261
13262    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13263        self.language_registry
13264            .update_lsp_binary_status(server_name, status);
13265    }
13266
13267    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13268        self.language_registry
13269            .all_lsp_adapters()
13270            .into_iter()
13271            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13272            .collect()
13273    }
13274
13275    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13276        let dir = self.language_registry.language_server_download_dir(name)?;
13277
13278        if !dir.exists() {
13279            smol::fs::create_dir_all(&dir)
13280                .await
13281                .context("failed to create container directory")
13282                .log_err()?;
13283        }
13284
13285        Some(dir)
13286    }
13287
13288    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
13289        let entry = self
13290            .worktree
13291            .entry_for_path(&path)
13292            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13293        let abs_path = self
13294            .worktree
13295            .absolutize(&entry.path)
13296            .with_context(|| format!("cannot absolutize path {path:?}"))?;
13297
13298        self.fs.load(&abs_path).await
13299    }
13300}
13301
13302async fn populate_labels_for_symbols(
13303    symbols: Vec<CoreSymbol>,
13304    language_registry: &Arc<LanguageRegistry>,
13305    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13306    output: &mut Vec<Symbol>,
13307) {
13308    #[allow(clippy::mutable_key_type)]
13309    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13310
13311    let mut unknown_paths = BTreeSet::new();
13312    for symbol in symbols {
13313        let language = language_registry
13314            .language_for_file_path(&symbol.path.path)
13315            .await
13316            .ok()
13317            .or_else(|| {
13318                unknown_paths.insert(symbol.path.path.clone());
13319                None
13320            });
13321        symbols_by_language
13322            .entry(language)
13323            .or_default()
13324            .push(symbol);
13325    }
13326
13327    for unknown_path in unknown_paths {
13328        log::info!(
13329            "no language found for symbol path {}",
13330            unknown_path.display()
13331        );
13332    }
13333
13334    let mut label_params = Vec::new();
13335    for (language, mut symbols) in symbols_by_language {
13336        label_params.clear();
13337        label_params.extend(
13338            symbols
13339                .iter_mut()
13340                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13341        );
13342
13343        let mut labels = Vec::new();
13344        if let Some(language) = language {
13345            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13346                language_registry
13347                    .lsp_adapters(&language.name())
13348                    .first()
13349                    .cloned()
13350            });
13351            if let Some(lsp_adapter) = lsp_adapter {
13352                labels = lsp_adapter
13353                    .labels_for_symbols(&label_params, &language)
13354                    .await
13355                    .log_err()
13356                    .unwrap_or_default();
13357            }
13358        }
13359
13360        for ((symbol, (name, _)), label) in symbols
13361            .into_iter()
13362            .zip(label_params.drain(..))
13363            .zip(labels.into_iter().chain(iter::repeat(None)))
13364        {
13365            output.push(Symbol {
13366                language_server_name: symbol.language_server_name,
13367                source_worktree_id: symbol.source_worktree_id,
13368                source_language_server_id: symbol.source_language_server_id,
13369                path: symbol.path,
13370                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13371                name,
13372                kind: symbol.kind,
13373                range: symbol.range,
13374                signature: symbol.signature,
13375            });
13376        }
13377    }
13378}
13379
13380fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13381    match server.capabilities().text_document_sync.as_ref()? {
13382        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13383            // Server wants didSave but didn't specify includeText.
13384            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13385            // Server doesn't want didSave at all.
13386            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13387            // Server provided SaveOptions.
13388            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13389                Some(save_options.include_text.unwrap_or(false))
13390            }
13391        },
13392        // We do not have any save info. Kind affects didChange only.
13393        lsp::TextDocumentSyncCapability::Kind(_) => None,
13394    }
13395}
13396
13397/// Completion items are displayed in a `UniformList`.
13398/// Usually, those items are single-line strings, but in LSP responses,
13399/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13400/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13401/// 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,
13402/// breaking the completions menu presentation.
13403///
13404/// 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.
13405fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13406    let mut new_text = String::with_capacity(label.text.len());
13407    let mut offset_map = vec![0; label.text.len() + 1];
13408    let mut last_char_was_space = false;
13409    let mut new_idx = 0;
13410    let chars = label.text.char_indices().fuse();
13411    let mut newlines_removed = false;
13412
13413    for (idx, c) in chars {
13414        offset_map[idx] = new_idx;
13415
13416        match c {
13417            '\n' if last_char_was_space => {
13418                newlines_removed = true;
13419            }
13420            '\t' | ' ' if last_char_was_space => {}
13421            '\n' if !last_char_was_space => {
13422                new_text.push(' ');
13423                new_idx += 1;
13424                last_char_was_space = true;
13425                newlines_removed = true;
13426            }
13427            ' ' | '\t' => {
13428                new_text.push(' ');
13429                new_idx += 1;
13430                last_char_was_space = true;
13431            }
13432            _ => {
13433                new_text.push(c);
13434                new_idx += c.len_utf8();
13435                last_char_was_space = false;
13436            }
13437        }
13438    }
13439    offset_map[label.text.len()] = new_idx;
13440
13441    // Only modify the label if newlines were removed.
13442    if !newlines_removed {
13443        return;
13444    }
13445
13446    let last_index = new_idx;
13447    let mut run_ranges_errors = Vec::new();
13448    label.runs.retain_mut(|(range, _)| {
13449        match offset_map.get(range.start) {
13450            Some(&start) => range.start = start,
13451            None => {
13452                run_ranges_errors.push(range.clone());
13453                return false;
13454            }
13455        }
13456
13457        match offset_map.get(range.end) {
13458            Some(&end) => range.end = end,
13459            None => {
13460                run_ranges_errors.push(range.clone());
13461                range.end = last_index;
13462            }
13463        }
13464        true
13465    });
13466    if !run_ranges_errors.is_empty() {
13467        log::error!(
13468            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13469            label.text
13470        );
13471    }
13472
13473    let mut wrong_filter_range = None;
13474    if label.filter_range == (0..label.text.len()) {
13475        label.filter_range = 0..new_text.len();
13476    } else {
13477        let mut original_filter_range = Some(label.filter_range.clone());
13478        match offset_map.get(label.filter_range.start) {
13479            Some(&start) => label.filter_range.start = start,
13480            None => {
13481                wrong_filter_range = original_filter_range.take();
13482                label.filter_range.start = last_index;
13483            }
13484        }
13485
13486        match offset_map.get(label.filter_range.end) {
13487            Some(&end) => label.filter_range.end = end,
13488            None => {
13489                wrong_filter_range = original_filter_range.take();
13490                label.filter_range.end = last_index;
13491            }
13492        }
13493    }
13494    if let Some(wrong_filter_range) = wrong_filter_range {
13495        log::error!(
13496            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13497            label.text
13498        );
13499    }
13500
13501    label.text = new_text;
13502}
13503
13504#[cfg(test)]
13505mod tests {
13506    use language::HighlightId;
13507
13508    use super::*;
13509
13510    #[test]
13511    fn test_glob_literal_prefix() {
13512        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13513        assert_eq!(
13514            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13515            Path::new("node_modules")
13516        );
13517        assert_eq!(
13518            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13519            Path::new("foo")
13520        );
13521        assert_eq!(
13522            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13523            Path::new("foo/bar/baz.js")
13524        );
13525
13526        #[cfg(target_os = "windows")]
13527        {
13528            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13529            assert_eq!(
13530                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13531                Path::new("node_modules")
13532            );
13533            assert_eq!(
13534                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13535                Path::new("foo")
13536            );
13537            assert_eq!(
13538                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13539                Path::new("foo/bar/baz.js")
13540            );
13541        }
13542    }
13543
13544    #[test]
13545    fn test_multi_len_chars_normalization() {
13546        let mut label = CodeLabel {
13547            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13548            runs: vec![(0..6, HighlightId(1))],
13549            filter_range: 0..6,
13550        };
13551        ensure_uniform_list_compatible_label(&mut label);
13552        assert_eq!(
13553            label,
13554            CodeLabel {
13555                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13556                runs: vec![(0..6, HighlightId(1))],
13557                filter_range: 0..6,
13558            }
13559        );
13560    }
13561}