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